{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleContexts #-}
module Stack.Build.Cache
( tryGetBuildCache
, tryGetConfigCache
, tryGetCabalMod
, tryGetSetupConfigMod
, getInstalledExes
, tryGetFlagCache
, deleteCaches
, markExeInstalled
, markExeNotInstalled
, writeFlagCache
, writeBuildCache
, writeConfigCache
, writeCabalMod
, TestStatus (..)
, setTestStatus
, getTestStatus
, writePrecompiledCache
, readPrecompiledCache
, BuildCache(..)
) where
import Stack.Prelude
import Crypto.Hash (hashWith, SHA256(..))
import qualified Data.ByteArray as Mem (convert)
import qualified Data.Map as M
import qualified Data.Set as Set
import qualified Data.Text as T
import qualified Data.Yaml as Yaml
import Foreign.C.Types (CTime)
import Path
import Path.IO
import Stack.Constants
import Stack.Constants.Config
import Stack.Storage.Project
import Stack.Storage.User
import Stack.Types.Build
import Stack.Types.Cache
import Stack.Types.Config
import Stack.Types.GhcPkgId
import Stack.Types.NamedComponent
import Stack.Types.SourceMap (smRelDir)
import System.PosixCompat.Files (modificationTime, getFileStatus, setFileTimes)
exeInstalledDir :: (HasEnvConfig env)
=> InstallLocation -> RIO env (Path Abs Dir)
exeInstalledDir :: InstallLocation -> RIO env (Path Abs Dir)
exeInstalledDir InstallLocation
Snap = (Path Abs Dir -> Path Rel Dir -> Path Abs Dir
forall b t. Path b Dir -> Path Rel t -> Path b t
</> Path Rel Dir
relDirInstalledPackages) (Path Abs Dir -> Path Abs Dir)
-> RIO env (Path Abs Dir) -> RIO env (Path Abs Dir)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` RIO env (Path Abs Dir)
forall env. HasEnvConfig env => RIO env (Path Abs Dir)
installationRootDeps
exeInstalledDir InstallLocation
Local = (Path Abs Dir -> Path Rel Dir -> Path Abs Dir
forall b t. Path b Dir -> Path Rel t -> Path b t
</> Path Rel Dir
relDirInstalledPackages) (Path Abs Dir -> Path Abs Dir)
-> RIO env (Path Abs Dir) -> RIO env (Path Abs Dir)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` RIO env (Path Abs Dir)
forall env. HasEnvConfig env => RIO env (Path Abs Dir)
installationRootLocal
getInstalledExes :: (HasEnvConfig env)
=> InstallLocation -> RIO env [PackageIdentifier]
getInstalledExes :: InstallLocation -> RIO env [PackageIdentifier]
getInstalledExes InstallLocation
loc = do
Path Abs Dir
dir <- InstallLocation -> RIO env (Path Abs Dir)
forall env.
HasEnvConfig env =>
InstallLocation -> RIO env (Path Abs Dir)
exeInstalledDir InstallLocation
loc
([Path Abs Dir]
_, [Path Abs File]
files) <- IO ([Path Abs Dir], [Path Abs File])
-> RIO env ([Path Abs Dir], [Path Abs File])
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ([Path Abs Dir], [Path Abs File])
-> RIO env ([Path Abs Dir], [Path Abs File]))
-> IO ([Path Abs Dir], [Path Abs File])
-> RIO env ([Path Abs Dir], [Path Abs File])
forall a b. (a -> b) -> a -> b
$ (IOException -> IO ([Path Abs Dir], [Path Abs File]))
-> IO ([Path Abs Dir], [Path Abs File])
-> IO ([Path Abs Dir], [Path Abs File])
forall (m :: * -> *) a.
MonadUnliftIO m =>
(IOException -> m a) -> m a -> m a
handleIO (IO ([Path Abs Dir], [Path Abs File])
-> IOException -> IO ([Path Abs Dir], [Path Abs File])
forall a b. a -> b -> a
const (IO ([Path Abs Dir], [Path Abs File])
-> IOException -> IO ([Path Abs Dir], [Path Abs File]))
-> IO ([Path Abs Dir], [Path Abs File])
-> IOException
-> IO ([Path Abs Dir], [Path Abs File])
forall a b. (a -> b) -> a -> b
$ ([Path Abs Dir], [Path Abs File])
-> IO ([Path Abs Dir], [Path Abs File])
forall (m :: * -> *) a. Monad m => a -> m a
return ([], [])) (IO ([Path Abs Dir], [Path Abs File])
-> IO ([Path Abs Dir], [Path Abs File]))
-> IO ([Path Abs Dir], [Path Abs File])
-> IO ([Path Abs Dir], [Path Abs File])
forall a b. (a -> b) -> a -> b
$ Path Abs Dir -> IO ([Path Abs Dir], [Path Abs File])
forall (m :: * -> *) b.
MonadIO m =>
Path b Dir -> m ([Path Abs Dir], [Path Abs File])
listDir Path Abs Dir
dir
[PackageIdentifier] -> RIO env [PackageIdentifier]
forall (m :: * -> *) a. Monad m => a -> m a
return ([PackageIdentifier] -> RIO env [PackageIdentifier])
-> [PackageIdentifier] -> RIO env [PackageIdentifier]
forall a b. (a -> b) -> a -> b
$
[[PackageIdentifier]] -> [PackageIdentifier]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[PackageIdentifier]] -> [PackageIdentifier])
-> [[PackageIdentifier]] -> [PackageIdentifier]
forall a b. (a -> b) -> a -> b
$
Map PackageName [PackageIdentifier] -> [[PackageIdentifier]]
forall k a. Map k a -> [a]
M.elems (Map PackageName [PackageIdentifier] -> [[PackageIdentifier]])
-> Map PackageName [PackageIdentifier] -> [[PackageIdentifier]]
forall a b. (a -> b) -> a -> b
$
([PackageIdentifier] -> [PackageIdentifier] -> [PackageIdentifier])
-> [(PackageName, [PackageIdentifier])]
-> Map PackageName [PackageIdentifier]
forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
M.fromListWith (\[PackageIdentifier]
_ [PackageIdentifier]
_ -> []) ([(PackageName, [PackageIdentifier])]
-> Map PackageName [PackageIdentifier])
-> [(PackageName, [PackageIdentifier])]
-> Map PackageName [PackageIdentifier]
forall a b. (a -> b) -> a -> b
$
(PackageIdentifier -> (PackageName, [PackageIdentifier]))
-> [PackageIdentifier] -> [(PackageName, [PackageIdentifier])]
forall a b. (a -> b) -> [a] -> [b]
map (\PackageIdentifier
x -> (PackageIdentifier -> PackageName
pkgName PackageIdentifier
x, [PackageIdentifier
x])) ([PackageIdentifier] -> [(PackageName, [PackageIdentifier])])
-> [PackageIdentifier] -> [(PackageName, [PackageIdentifier])]
forall a b. (a -> b) -> a -> b
$
(Path Abs File -> Maybe PackageIdentifier)
-> [Path Abs File] -> [PackageIdentifier]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (String -> Maybe PackageIdentifier
parsePackageIdentifier (String -> Maybe PackageIdentifier)
-> (Path Abs File -> String)
-> Path Abs File
-> Maybe PackageIdentifier
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Path Rel File -> String
forall b t. Path b t -> String
toFilePath (Path Rel File -> String)
-> (Path Abs File -> Path Rel File) -> Path Abs File -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Path Abs File -> Path Rel File
forall b. Path b File -> Path Rel File
filename) [Path Abs File]
files
markExeInstalled :: (HasEnvConfig env)
=> InstallLocation -> PackageIdentifier -> RIO env ()
markExeInstalled :: InstallLocation -> PackageIdentifier -> RIO env ()
markExeInstalled InstallLocation
loc PackageIdentifier
ident = do
Path Abs Dir
dir <- InstallLocation -> RIO env (Path Abs Dir)
forall env.
HasEnvConfig env =>
InstallLocation -> RIO env (Path Abs Dir)
exeInstalledDir InstallLocation
loc
Path Abs Dir -> RIO env ()
forall (m :: * -> *) b. MonadIO m => Path b Dir -> m ()
ensureDir Path Abs Dir
dir
Path Rel File
ident' <- String -> RIO env (Path Rel File)
forall (m :: * -> *). MonadThrow m => String -> m (Path Rel File)
parseRelFile (String -> RIO env (Path Rel File))
-> String -> RIO env (Path Rel File)
forall a b. (a -> b) -> a -> b
$ PackageIdentifier -> String
packageIdentifierString PackageIdentifier
ident
let fp :: Path Abs File
fp = Path Abs Dir
dir Path Abs Dir -> Path Rel File -> Path Abs File
forall b t. Path b Dir -> Path Rel t -> Path b t
</> Path Rel File
ident'
[PackageIdentifier]
installed <- InstallLocation -> RIO env [PackageIdentifier]
forall env.
HasEnvConfig env =>
InstallLocation -> RIO env [PackageIdentifier]
getInstalledExes InstallLocation
loc
[PackageIdentifier]
-> (PackageIdentifier -> RIO env ()) -> RIO env ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ ((PackageIdentifier -> Bool)
-> [PackageIdentifier] -> [PackageIdentifier]
forall a. (a -> Bool) -> [a] -> [a]
filter (\PackageIdentifier
x -> PackageIdentifier -> PackageName
pkgName PackageIdentifier
ident PackageName -> PackageName -> Bool
forall a. Eq a => a -> a -> Bool
== PackageIdentifier -> PackageName
pkgName PackageIdentifier
x) [PackageIdentifier]
installed)
(InstallLocation -> PackageIdentifier -> RIO env ()
forall env.
HasEnvConfig env =>
InstallLocation -> PackageIdentifier -> RIO env ()
markExeNotInstalled InstallLocation
loc)
Path Abs File -> Builder -> RIO env ()
forall (m :: * -> *) absrel.
MonadIO m =>
Path absrel File -> Builder -> m ()
writeBinaryFileAtomic Path Abs File
fp Builder
"Installed"
markExeNotInstalled :: (HasEnvConfig env)
=> InstallLocation -> PackageIdentifier -> RIO env ()
markExeNotInstalled :: InstallLocation -> PackageIdentifier -> RIO env ()
markExeNotInstalled InstallLocation
loc PackageIdentifier
ident = do
Path Abs Dir
dir <- InstallLocation -> RIO env (Path Abs Dir)
forall env.
HasEnvConfig env =>
InstallLocation -> RIO env (Path Abs Dir)
exeInstalledDir InstallLocation
loc
Path Rel File
ident' <- String -> RIO env (Path Rel File)
forall (m :: * -> *). MonadThrow m => String -> m (Path Rel File)
parseRelFile (String -> RIO env (Path Rel File))
-> String -> RIO env (Path Rel File)
forall a b. (a -> b) -> a -> b
$ PackageIdentifier -> String
packageIdentifierString PackageIdentifier
ident
IO () -> RIO env ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> RIO env ()) -> IO () -> RIO env ()
forall a b. (a -> b) -> a -> b
$ IO () -> IO ()
forall (m :: * -> *) a. (MonadIO m, MonadCatch m) => m a -> m ()
ignoringAbsence (Path Abs File -> IO ()
forall (m :: * -> *) b. MonadIO m => Path b File -> m ()
removeFile (Path Abs File -> IO ()) -> Path Abs File -> IO ()
forall a b. (a -> b) -> a -> b
$ Path Abs Dir
dir Path Abs Dir -> Path Rel File -> Path Abs File
forall b t. Path b Dir -> Path Rel t -> Path b t
</> Path Rel File
ident')
buildCacheFile :: (HasEnvConfig env, MonadReader env m, MonadThrow m)
=> Path Abs Dir
-> NamedComponent
-> m (Path Abs File)
buildCacheFile :: Path Abs Dir -> NamedComponent -> m (Path Abs File)
buildCacheFile Path Abs Dir
dir NamedComponent
component = do
Path Abs Dir
cachesDir <- Path Abs Dir -> m (Path Abs Dir)
forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs Dir)
buildCachesDir Path Abs Dir
dir
SourceMapHash
smh <- Getting SourceMapHash env SourceMapHash -> m SourceMapHash
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view (Getting SourceMapHash env SourceMapHash -> m SourceMapHash)
-> Getting SourceMapHash env SourceMapHash -> m SourceMapHash
forall a b. (a -> b) -> a -> b
$ (EnvConfig -> Const SourceMapHash EnvConfig)
-> env -> Const SourceMapHash env
forall env. HasEnvConfig env => Lens' env EnvConfig
envConfigL((EnvConfig -> Const SourceMapHash EnvConfig)
-> env -> Const SourceMapHash env)
-> ((SourceMapHash -> Const SourceMapHash SourceMapHash)
-> EnvConfig -> Const SourceMapHash EnvConfig)
-> Getting SourceMapHash env SourceMapHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(EnvConfig -> SourceMapHash)
-> SimpleGetter EnvConfig SourceMapHash
forall s a. (s -> a) -> SimpleGetter s a
to EnvConfig -> SourceMapHash
envConfigSourceMapHash
Path Rel Dir
smDirName <- SourceMapHash -> m (Path Rel Dir)
forall (m :: * -> *).
MonadThrow m =>
SourceMapHash -> m (Path Rel Dir)
smRelDir SourceMapHash
smh
let nonLibComponent :: String -> Text -> String
nonLibComponent String
prefix Text
name = String
prefix String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"-" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
name
Path Rel File
cacheFileName <- String -> m (Path Rel File)
forall (m :: * -> *). MonadThrow m => String -> m (Path Rel File)
parseRelFile (String -> m (Path Rel File)) -> String -> m (Path Rel File)
forall a b. (a -> b) -> a -> b
$ case NamedComponent
component of
NamedComponent
CLib -> String
"lib"
CInternalLib Text
name -> String -> Text -> String
nonLibComponent String
"internal-lib" Text
name
CExe Text
name -> String -> Text -> String
nonLibComponent String
"exe" Text
name
CTest Text
name -> String -> Text -> String
nonLibComponent String
"test" Text
name
CBench Text
name -> String -> Text -> String
nonLibComponent String
"bench" Text
name
Path Abs File -> m (Path Abs File)
forall (m :: * -> *) a. Monad m => a -> m a
return (Path Abs File -> m (Path Abs File))
-> Path Abs File -> m (Path Abs File)
forall a b. (a -> b) -> a -> b
$ Path Abs Dir
cachesDir Path Abs Dir -> Path Rel File -> Path Abs File
forall b t. Path b Dir -> Path Rel t -> Path b t
</> Path Rel Dir
smDirName Path Rel Dir -> Path Rel File -> Path Rel File
forall b t. Path b Dir -> Path Rel t -> Path b t
</> Path Rel File
cacheFileName
tryGetBuildCache :: HasEnvConfig env
=> Path Abs Dir
-> NamedComponent
-> RIO env (Maybe (Map FilePath FileCacheInfo))
tryGetBuildCache :: Path Abs Dir
-> NamedComponent -> RIO env (Maybe (Map String FileCacheInfo))
tryGetBuildCache Path Abs Dir
dir NamedComponent
component = do
Path Abs File
fp <- Path Abs Dir -> NamedComponent -> RIO env (Path Abs File)
forall env (m :: * -> *).
(HasEnvConfig env, MonadReader env m, MonadThrow m) =>
Path Abs Dir -> NamedComponent -> m (Path Abs File)
buildCacheFile Path Abs Dir
dir NamedComponent
component
Path Abs Dir -> RIO env ()
forall (m :: * -> *) b. MonadIO m => Path b Dir -> m ()
ensureDir (Path Abs Dir -> RIO env ()) -> Path Abs Dir -> RIO env ()
forall a b. (a -> b) -> a -> b
$ Path Abs File -> Path Abs Dir
forall b t. Path b t -> Path b Dir
parent Path Abs File
fp
(SomeException -> Maybe (Map String FileCacheInfo))
-> (BuildCache -> Maybe (Map String FileCacheInfo))
-> Either SomeException BuildCache
-> Maybe (Map String FileCacheInfo)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe (Map String FileCacheInfo)
-> SomeException -> Maybe (Map String FileCacheInfo)
forall a b. a -> b -> a
const Maybe (Map String FileCacheInfo)
forall a. Maybe a
Nothing) (Map String FileCacheInfo -> Maybe (Map String FileCacheInfo)
forall a. a -> Maybe a
Just (Map String FileCacheInfo -> Maybe (Map String FileCacheInfo))
-> (BuildCache -> Map String FileCacheInfo)
-> BuildCache
-> Maybe (Map String FileCacheInfo)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BuildCache -> Map String FileCacheInfo
buildCacheTimes) (Either SomeException BuildCache
-> Maybe (Map String FileCacheInfo))
-> RIO env (Either SomeException BuildCache)
-> RIO env (Maybe (Map String FileCacheInfo))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
IO (Either SomeException BuildCache)
-> RIO env (Either SomeException BuildCache)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO BuildCache -> IO (Either SomeException BuildCache)
forall (m :: * -> *) a.
MonadUnliftIO m =>
m a -> m (Either SomeException a)
tryAny (String -> IO BuildCache
forall (m :: * -> *) a. (MonadIO m, FromJSON a) => String -> m a
Yaml.decodeFileThrow (Path Abs File -> String
forall b t. Path b t -> String
toFilePath Path Abs File
fp)))
tryGetConfigCache :: HasEnvConfig env
=> Path Abs Dir -> RIO env (Maybe ConfigCache)
tryGetConfigCache :: Path Abs Dir -> RIO env (Maybe ConfigCache)
tryGetConfigCache Path Abs Dir
dir =
ConfigCacheKey -> RIO env (Maybe ConfigCache)
forall env.
(HasBuildConfig env, HasLogFunc env) =>
ConfigCacheKey -> RIO env (Maybe ConfigCache)
loadConfigCache (ConfigCacheKey -> RIO env (Maybe ConfigCache))
-> ConfigCacheKey -> RIO env (Maybe ConfigCache)
forall a b. (a -> b) -> a -> b
$ Path Abs Dir -> ConfigCacheType -> ConfigCacheKey
configCacheKey Path Abs Dir
dir ConfigCacheType
ConfigCacheTypeConfig
tryGetCabalMod :: HasEnvConfig env
=> Path Abs Dir -> RIO env (Maybe CTime)
tryGetCabalMod :: Path Abs Dir -> RIO env (Maybe CTime)
tryGetCabalMod Path Abs Dir
dir = do
String
fp <- Path Abs File -> String
forall b t. Path b t -> String
toFilePath (Path Abs File -> String)
-> RIO env (Path Abs File) -> RIO env String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Path Abs Dir -> RIO env (Path Abs File)
forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs File)
configCabalMod Path Abs Dir
dir
String -> RIO env (Maybe CTime)
forall (m :: * -> *). MonadIO m => String -> m (Maybe CTime)
tryGetFileMod String
fp
tryGetSetupConfigMod :: HasEnvConfig env
=> Path Abs Dir -> RIO env (Maybe CTime)
tryGetSetupConfigMod :: Path Abs Dir -> RIO env (Maybe CTime)
tryGetSetupConfigMod Path Abs Dir
dir = do
String
fp <- Path Abs File -> String
forall b t. Path b t -> String
toFilePath (Path Abs File -> String)
-> RIO env (Path Abs File) -> RIO env String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Path Abs Dir -> RIO env (Path Abs File)
forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs File)
configSetupConfigMod Path Abs Dir
dir
String -> RIO env (Maybe CTime)
forall (m :: * -> *). MonadIO m => String -> m (Maybe CTime)
tryGetFileMod String
fp
tryGetFileMod :: MonadIO m => FilePath -> m (Maybe CTime)
tryGetFileMod :: String -> m (Maybe CTime)
tryGetFileMod String
fp =
IO (Maybe CTime) -> m (Maybe CTime)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe CTime) -> m (Maybe CTime))
-> IO (Maybe CTime) -> m (Maybe CTime)
forall a b. (a -> b) -> a -> b
$ (IOException -> Maybe CTime)
-> (FileStatus -> Maybe CTime)
-> Either IOException FileStatus
-> Maybe CTime
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe CTime -> IOException -> Maybe CTime
forall a b. a -> b -> a
const Maybe CTime
forall a. Maybe a
Nothing) (CTime -> Maybe CTime
forall a. a -> Maybe a
Just (CTime -> Maybe CTime)
-> (FileStatus -> CTime) -> FileStatus -> Maybe CTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FileStatus -> CTime
modificationTime) (Either IOException FileStatus -> Maybe CTime)
-> IO (Either IOException FileStatus) -> IO (Maybe CTime)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
IO FileStatus -> IO (Either IOException FileStatus)
forall (m :: * -> *) a.
MonadUnliftIO m =>
m a -> m (Either IOException a)
tryIO (String -> IO FileStatus
getFileStatus String
fp)
writeBuildCache :: HasEnvConfig env
=> Path Abs Dir
-> NamedComponent
-> Map FilePath FileCacheInfo -> RIO env ()
writeBuildCache :: Path Abs Dir
-> NamedComponent -> Map String FileCacheInfo -> RIO env ()
writeBuildCache Path Abs Dir
dir NamedComponent
component Map String FileCacheInfo
times = do
String
fp <- Path Abs File -> String
forall b t. Path b t -> String
toFilePath (Path Abs File -> String)
-> RIO env (Path Abs File) -> RIO env String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Path Abs Dir -> NamedComponent -> RIO env (Path Abs File)
forall env (m :: * -> *).
(HasEnvConfig env, MonadReader env m, MonadThrow m) =>
Path Abs Dir -> NamedComponent -> m (Path Abs File)
buildCacheFile Path Abs Dir
dir NamedComponent
component
IO () -> RIO env ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> RIO env ()) -> IO () -> RIO env ()
forall a b. (a -> b) -> a -> b
$ String -> BuildCache -> IO ()
forall a. ToJSON a => String -> a -> IO ()
Yaml.encodeFile String
fp BuildCache :: Map String FileCacheInfo -> BuildCache
BuildCache
{ buildCacheTimes :: Map String FileCacheInfo
buildCacheTimes = Map String FileCacheInfo
times
}
writeConfigCache :: HasEnvConfig env
=> Path Abs Dir
-> ConfigCache
-> RIO env ()
writeConfigCache :: Path Abs Dir -> ConfigCache -> RIO env ()
writeConfigCache Path Abs Dir
dir =
ConfigCacheKey -> ConfigCache -> RIO env ()
forall env.
(HasBuildConfig env, HasLogFunc env) =>
ConfigCacheKey -> ConfigCache -> RIO env ()
saveConfigCache (Path Abs Dir -> ConfigCacheType -> ConfigCacheKey
configCacheKey Path Abs Dir
dir ConfigCacheType
ConfigCacheTypeConfig)
writeCabalMod :: HasEnvConfig env
=> Path Abs Dir
-> CTime
-> RIO env ()
writeCabalMod :: Path Abs Dir -> CTime -> RIO env ()
writeCabalMod Path Abs Dir
dir CTime
x = do
Path Abs File
fp <- Path Abs Dir -> RIO env (Path Abs File)
forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs File)
configCabalMod Path Abs Dir
dir
Path Abs File -> Builder -> RIO env ()
forall (m :: * -> *) absrel.
MonadIO m =>
Path absrel File -> Builder -> m ()
writeBinaryFileAtomic Path Abs File
fp Builder
"Just used for its modification time"
IO () -> RIO env ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> RIO env ()) -> IO () -> RIO env ()
forall a b. (a -> b) -> a -> b
$ String -> CTime -> CTime -> IO ()
setFileTimes (Path Abs File -> String
forall b t. Path b t -> String
toFilePath Path Abs File
fp) CTime
x CTime
x
deleteCaches :: HasEnvConfig env => Path Abs Dir -> RIO env ()
deleteCaches :: Path Abs Dir -> RIO env ()
deleteCaches Path Abs Dir
dir
= ConfigCacheKey -> RIO env ()
forall env. HasBuildConfig env => ConfigCacheKey -> RIO env ()
deactiveConfigCache (ConfigCacheKey -> RIO env ()) -> ConfigCacheKey -> RIO env ()
forall a b. (a -> b) -> a -> b
$ Path Abs Dir -> ConfigCacheType -> ConfigCacheKey
configCacheKey Path Abs Dir
dir ConfigCacheType
ConfigCacheTypeConfig
flagCacheKey :: (HasEnvConfig env) => Installed -> RIO env ConfigCacheKey
flagCacheKey :: Installed -> RIO env ConfigCacheKey
flagCacheKey Installed
installed = do
Path Abs Dir
installationRoot <- RIO env (Path Abs Dir)
forall env. HasEnvConfig env => RIO env (Path Abs Dir)
installationRootLocal
case Installed
installed of
Library PackageIdentifier
_ GhcPkgId
gid Maybe (Either License License)
_ ->
ConfigCacheKey -> RIO env ConfigCacheKey
forall (m :: * -> *) a. Monad m => a -> m a
return (ConfigCacheKey -> RIO env ConfigCacheKey)
-> ConfigCacheKey -> RIO env ConfigCacheKey
forall a b. (a -> b) -> a -> b
$
Path Abs Dir -> ConfigCacheType -> ConfigCacheKey
configCacheKey Path Abs Dir
installationRoot (GhcPkgId -> ConfigCacheType
ConfigCacheTypeFlagLibrary GhcPkgId
gid)
Executable PackageIdentifier
ident ->
ConfigCacheKey -> RIO env ConfigCacheKey
forall (m :: * -> *) a. Monad m => a -> m a
return (ConfigCacheKey -> RIO env ConfigCacheKey)
-> ConfigCacheKey -> RIO env ConfigCacheKey
forall a b. (a -> b) -> a -> b
$
Path Abs Dir -> ConfigCacheType -> ConfigCacheKey
configCacheKey
Path Abs Dir
installationRoot
(PackageIdentifier -> ConfigCacheType
ConfigCacheTypeFlagExecutable PackageIdentifier
ident)
tryGetFlagCache :: HasEnvConfig env
=> Installed
-> RIO env (Maybe ConfigCache)
tryGetFlagCache :: Installed -> RIO env (Maybe ConfigCache)
tryGetFlagCache Installed
gid = do
ConfigCacheKey
key <- Installed -> RIO env ConfigCacheKey
forall env. HasEnvConfig env => Installed -> RIO env ConfigCacheKey
flagCacheKey Installed
gid
ConfigCacheKey -> RIO env (Maybe ConfigCache)
forall env.
(HasBuildConfig env, HasLogFunc env) =>
ConfigCacheKey -> RIO env (Maybe ConfigCache)
loadConfigCache ConfigCacheKey
key
writeFlagCache :: HasEnvConfig env
=> Installed
-> ConfigCache
-> RIO env ()
writeFlagCache :: Installed -> ConfigCache -> RIO env ()
writeFlagCache Installed
gid ConfigCache
cache = do
ConfigCacheKey
key <- Installed -> RIO env ConfigCacheKey
forall env. HasEnvConfig env => Installed -> RIO env ConfigCacheKey
flagCacheKey Installed
gid
ConfigCacheKey -> ConfigCache -> RIO env ()
forall env.
(HasBuildConfig env, HasLogFunc env) =>
ConfigCacheKey -> ConfigCache -> RIO env ()
saveConfigCache ConfigCacheKey
key ConfigCache
cache
successBS, failureBS, unknownBS :: IsString s => s
successBS :: s
successBS = s
"success"
failureBS :: s
failureBS = s
"failure"
unknownBS :: s
unknownBS = s
"unknown"
data TestStatus = TSSuccess | TSFailure | TSUnknown
setTestStatus :: HasEnvConfig env
=> Path Abs Dir
-> TestStatus
-> RIO env ()
setTestStatus :: Path Abs Dir -> TestStatus -> RIO env ()
setTestStatus Path Abs Dir
dir TestStatus
status = do
Path Abs File
fp <- Path Abs Dir -> RIO env (Path Abs File)
forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs File)
testSuccessFile Path Abs Dir
dir
Path Abs File -> Builder -> RIO env ()
forall (m :: * -> *) absrel.
MonadIO m =>
Path absrel File -> Builder -> m ()
writeBinaryFileAtomic Path Abs File
fp (Builder -> RIO env ()) -> Builder -> RIO env ()
forall a b. (a -> b) -> a -> b
$
case TestStatus
status of
TestStatus
TSSuccess -> Builder
forall s. IsString s => s
successBS
TestStatus
TSFailure -> Builder
forall s. IsString s => s
failureBS
TestStatus
TSUnknown -> Builder
forall s. IsString s => s
unknownBS
getTestStatus :: HasEnvConfig env
=> Path Abs Dir
-> RIO env TestStatus
getTestStatus :: Path Abs Dir -> RIO env TestStatus
getTestStatus Path Abs Dir
dir = do
Path Abs File
fp <- Path Abs Dir -> RIO env (Path Abs File)
forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs File)
testSuccessFile Path Abs Dir
dir
Either IOException ByteString
eres <- RIO env ByteString -> RIO env (Either IOException ByteString)
forall (m :: * -> *) a.
MonadUnliftIO m =>
m a -> m (Either IOException a)
tryIO (String -> RIO env ByteString
forall (m :: * -> *). MonadIO m => String -> m ByteString
readFileBinary (String -> RIO env ByteString) -> String -> RIO env ByteString
forall a b. (a -> b) -> a -> b
$ Path Abs File -> String
forall b t. Path b t -> String
toFilePath Path Abs File
fp)
TestStatus -> RIO env TestStatus
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TestStatus -> RIO env TestStatus)
-> TestStatus -> RIO env TestStatus
forall a b. (a -> b) -> a -> b
$
case Either IOException ByteString
eres of
Right ByteString
bs
| ByteString
bs ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
forall s. IsString s => s
successBS -> TestStatus
TSSuccess
| ByteString
bs ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
forall s. IsString s => s
failureBS -> TestStatus
TSFailure
Either IOException ByteString
_ -> TestStatus
TSUnknown
getPrecompiledCacheKey :: HasEnvConfig env
=> PackageLocationImmutable
-> ConfigureOpts
-> Bool
-> Set GhcPkgId
-> RIO env PrecompiledCacheKey
getPrecompiledCacheKey :: PackageLocationImmutable
-> ConfigureOpts
-> Bool
-> Set GhcPkgId
-> RIO env PrecompiledCacheKey
getPrecompiledCacheKey PackageLocationImmutable
loc ConfigureOpts
copts Bool
buildHaddocks Set GhcPkgId
installedPackageIDs = do
ActualCompiler
compiler <- Getting ActualCompiler env ActualCompiler -> RIO env ActualCompiler
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting ActualCompiler env ActualCompiler
forall env. HasSourceMap env => SimpleGetter env ActualCompiler
actualCompilerVersionL
Version
cabalVersion <- Getting Version env Version -> RIO env Version
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Version env Version
forall env. HasCompiler env => SimpleGetter env Version
cabalVersionL
TreeKey
treeKey <- PackageLocationImmutable -> RIO env TreeKey
forall env.
(HasPantryConfig env, HasLogFunc env, HasProcessContext env) =>
PackageLocationImmutable -> RIO env TreeKey
getPackageLocationTreeKey PackageLocationImmutable
loc
let packageKey :: Text
packageKey = Utf8Builder -> Text
utf8BuilderToText (Utf8Builder -> Text) -> Utf8Builder -> Text
forall a b. (a -> b) -> a -> b
$ TreeKey -> Utf8Builder
forall a. Display a => a -> Utf8Builder
display TreeKey
treeKey
Path Rel Dir
platformGhcDir <- RIO env (Path Rel Dir)
forall env (m :: * -> *).
(MonadReader env m, HasEnvConfig env, MonadThrow m) =>
m (Path Rel Dir)
platformGhcRelDir
let input :: ([String], Set GhcPkgId)
input = (ConfigureOpts -> [String]
coNoDirs ConfigureOpts
copts, Set GhcPkgId
installedPackageIDs)
optionsHash :: ByteString
optionsHash = Digest SHA256 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
Mem.convert (Digest SHA256 -> ByteString) -> Digest SHA256 -> ByteString
forall a b. (a -> b) -> a -> b
$ SHA256 -> ByteString -> Digest SHA256
forall ba alg.
(ByteArrayAccess ba, HashAlgorithm alg) =>
alg -> ba -> Digest alg
hashWith SHA256
SHA256 (ByteString -> Digest SHA256) -> ByteString -> Digest SHA256
forall a b. (a -> b) -> a -> b
$ Text -> ByteString
encodeUtf8 (Text -> ByteString) -> Text -> ByteString
forall a b. (a -> b) -> a -> b
$ ([String], Set GhcPkgId) -> Text
forall a. Show a => a -> Text
tshow ([String], Set GhcPkgId)
input
PrecompiledCacheKey -> RIO env PrecompiledCacheKey
forall (m :: * -> *) a. Monad m => a -> m a
return (PrecompiledCacheKey -> RIO env PrecompiledCacheKey)
-> PrecompiledCacheKey -> RIO env PrecompiledCacheKey
forall a b. (a -> b) -> a -> b
$ Path Rel Dir
-> ActualCompiler
-> Version
-> Text
-> ByteString
-> Bool
-> PrecompiledCacheKey
precompiledCacheKey Path Rel Dir
platformGhcDir ActualCompiler
compiler Version
cabalVersion Text
packageKey ByteString
optionsHash Bool
buildHaddocks
writePrecompiledCache :: HasEnvConfig env
=> BaseConfigOpts
-> PackageLocationImmutable
-> ConfigureOpts
-> Bool
-> Set GhcPkgId
-> Installed
-> [GhcPkgId]
-> Set Text
-> RIO env ()
writePrecompiledCache :: BaseConfigOpts
-> PackageLocationImmutable
-> ConfigureOpts
-> Bool
-> Set GhcPkgId
-> Installed
-> [GhcPkgId]
-> Set Text
-> RIO env ()
writePrecompiledCache BaseConfigOpts
baseConfigOpts PackageLocationImmutable
loc ConfigureOpts
copts Bool
buildHaddocks Set GhcPkgId
depIDs Installed
mghcPkgId [GhcPkgId]
sublibs Set Text
exes = do
PrecompiledCacheKey
key <- PackageLocationImmutable
-> ConfigureOpts
-> Bool
-> Set GhcPkgId
-> RIO env PrecompiledCacheKey
forall env.
HasEnvConfig env =>
PackageLocationImmutable
-> ConfigureOpts
-> Bool
-> Set GhcPkgId
-> RIO env PrecompiledCacheKey
getPrecompiledCacheKey PackageLocationImmutable
loc ConfigureOpts
copts Bool
buildHaddocks Set GhcPkgId
depIDs
EnvConfig
ec <- Getting EnvConfig env EnvConfig -> RIO env EnvConfig
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting EnvConfig env EnvConfig
forall env. HasEnvConfig env => Lens' env EnvConfig
envConfigL
let stackRootRelative :: Path Abs File -> RIO env (RelPath (Path Abs File))
stackRootRelative = Path Abs Dir -> Path Abs File -> RIO env (RelPath (Path Abs File))
forall path (m :: * -> *).
(AnyPath path, MonadThrow m) =>
Path Abs Dir -> path -> m (RelPath path)
makeRelative (Getting (Path Abs Dir) EnvConfig (Path Abs Dir)
-> EnvConfig -> Path Abs Dir
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (Path Abs Dir) EnvConfig (Path Abs Dir)
forall s. HasConfig s => Lens' s (Path Abs Dir)
stackRootL EnvConfig
ec)
Maybe (Path Rel File)
mlibpath <- case Installed
mghcPkgId of
Executable PackageIdentifier
_ -> Maybe (Path Rel File) -> RIO env (Maybe (Path Rel File))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Path Rel File)
forall a. Maybe a
Nothing
Library PackageIdentifier
_ GhcPkgId
ipid Maybe (Either License License)
_ -> Path Rel File -> Maybe (Path Rel File)
forall a. a -> Maybe a
Just (Path Rel File -> Maybe (Path Rel File))
-> RIO env (Path Rel File) -> RIO env (Maybe (Path Rel File))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Path Abs File -> RIO env (Path Rel File))
-> GhcPkgId -> RIO env (Path Rel File)
forall (m :: * -> *) b.
MonadThrow m =>
(Path Abs File -> m b) -> GhcPkgId -> m b
pathFromPkgId Path Abs File -> RIO env (Path Rel File)
Path Abs File -> RIO env (RelPath (Path Abs File))
stackRootRelative GhcPkgId
ipid
[Path Rel File]
sublibpaths <- (GhcPkgId -> RIO env (Path Rel File))
-> [GhcPkgId] -> RIO env [Path Rel File]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ((Path Abs File -> RIO env (Path Rel File))
-> GhcPkgId -> RIO env (Path Rel File)
forall (m :: * -> *) b.
MonadThrow m =>
(Path Abs File -> m b) -> GhcPkgId -> m b
pathFromPkgId Path Abs File -> RIO env (Path Rel File)
Path Abs File -> RIO env (RelPath (Path Abs File))
stackRootRelative) [GhcPkgId]
sublibs
[Path Rel File]
exes' <- [Text]
-> (Text -> RIO env (Path Rel File)) -> RIO env [Path Rel File]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM (Set Text -> [Text]
forall a. Set a -> [a]
Set.toList Set Text
exes) ((Text -> RIO env (Path Rel File)) -> RIO env [Path Rel File])
-> (Text -> RIO env (Path Rel File)) -> RIO env [Path Rel File]
forall a b. (a -> b) -> a -> b
$ \Text
exe -> do
Path Rel File
name <- String -> RIO env (Path Rel File)
forall (m :: * -> *). MonadThrow m => String -> m (Path Rel File)
parseRelFile (String -> RIO env (Path Rel File))
-> String -> RIO env (Path Rel File)
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack Text
exe
Path Abs File -> RIO env (RelPath (Path Abs File))
stackRootRelative (Path Abs File -> RIO env (RelPath (Path Abs File)))
-> Path Abs File -> RIO env (RelPath (Path Abs File))
forall a b. (a -> b) -> a -> b
$ BaseConfigOpts -> Path Abs Dir
bcoSnapInstallRoot BaseConfigOpts
baseConfigOpts Path Abs Dir -> Path Rel File -> Path Abs File
forall b t. Path b Dir -> Path Rel t -> Path b t
</> Path Rel Dir
bindirSuffix Path Rel Dir -> Path Rel File -> Path Rel File
forall b t. Path b Dir -> Path Rel t -> Path b t
</> Path Rel File
name
let precompiled :: PrecompiledCache Rel
precompiled = PrecompiledCache :: forall base.
Maybe (Path base File)
-> [Path base File] -> [Path base File] -> PrecompiledCache base
PrecompiledCache
{ pcLibrary :: Maybe (Path Rel File)
pcLibrary = Maybe (Path Rel File)
mlibpath
, pcSubLibs :: [Path Rel File]
pcSubLibs = [Path Rel File]
sublibpaths
, pcExes :: [Path Rel File]
pcExes = [Path Rel File]
exes'
}
PrecompiledCacheKey -> PrecompiledCache Rel -> RIO env ()
forall env.
(HasConfig env, HasLogFunc env) =>
PrecompiledCacheKey -> PrecompiledCache Rel -> RIO env ()
savePrecompiledCache PrecompiledCacheKey
key PrecompiledCache Rel
precompiled
Bool -> RIO env () -> RIO env ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
buildHaddocks (RIO env () -> RIO env ()) -> RIO env () -> RIO env ()
forall a b. (a -> b) -> a -> b
$ do
PrecompiledCacheKey
key' <- PackageLocationImmutable
-> ConfigureOpts
-> Bool
-> Set GhcPkgId
-> RIO env PrecompiledCacheKey
forall env.
HasEnvConfig env =>
PackageLocationImmutable
-> ConfigureOpts
-> Bool
-> Set GhcPkgId
-> RIO env PrecompiledCacheKey
getPrecompiledCacheKey PackageLocationImmutable
loc ConfigureOpts
copts Bool
False Set GhcPkgId
depIDs
PrecompiledCacheKey -> PrecompiledCache Rel -> RIO env ()
forall env.
(HasConfig env, HasLogFunc env) =>
PrecompiledCacheKey -> PrecompiledCache Rel -> RIO env ()
savePrecompiledCache PrecompiledCacheKey
key' PrecompiledCache Rel
precompiled
where
pathFromPkgId :: (Path Abs File -> m b) -> GhcPkgId -> m b
pathFromPkgId Path Abs File -> m b
stackRootRelative GhcPkgId
ipid = do
Path Rel File
ipid' <- String -> m (Path Rel File)
forall (m :: * -> *). MonadThrow m => String -> m (Path Rel File)
parseRelFile (String -> m (Path Rel File)) -> String -> m (Path Rel File)
forall a b. (a -> b) -> a -> b
$ GhcPkgId -> String
ghcPkgIdString GhcPkgId
ipid String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
".conf"
Path Abs File -> m b
stackRootRelative (Path Abs File -> m b) -> Path Abs File -> m b
forall a b. (a -> b) -> a -> b
$ BaseConfigOpts -> Path Abs Dir
bcoSnapDB BaseConfigOpts
baseConfigOpts Path Abs Dir -> Path Rel File -> Path Abs File
forall b t. Path b Dir -> Path Rel t -> Path b t
</> Path Rel File
ipid'
readPrecompiledCache :: forall env. HasEnvConfig env
=> PackageLocationImmutable
-> ConfigureOpts
-> Bool
-> Set GhcPkgId
-> RIO env (Maybe (PrecompiledCache Abs))
readPrecompiledCache :: PackageLocationImmutable
-> ConfigureOpts
-> Bool
-> Set GhcPkgId
-> RIO env (Maybe (PrecompiledCache Abs))
readPrecompiledCache PackageLocationImmutable
loc ConfigureOpts
copts Bool
buildHaddocks Set GhcPkgId
depIDs = do
PrecompiledCacheKey
key <- PackageLocationImmutable
-> ConfigureOpts
-> Bool
-> Set GhcPkgId
-> RIO env PrecompiledCacheKey
forall env.
HasEnvConfig env =>
PackageLocationImmutable
-> ConfigureOpts
-> Bool
-> Set GhcPkgId
-> RIO env PrecompiledCacheKey
getPrecompiledCacheKey PackageLocationImmutable
loc ConfigureOpts
copts Bool
buildHaddocks Set GhcPkgId
depIDs
Maybe (PrecompiledCache Rel)
mcache <- PrecompiledCacheKey -> RIO env (Maybe (PrecompiledCache Rel))
forall env.
(HasConfig env, HasLogFunc env) =>
PrecompiledCacheKey -> RIO env (Maybe (PrecompiledCache Rel))
loadPrecompiledCache PrecompiledCacheKey
key
RIO env (Maybe (PrecompiledCache Abs))
-> (PrecompiledCache Rel -> RIO env (Maybe (PrecompiledCache Abs)))
-> Maybe (PrecompiledCache Rel)
-> RIO env (Maybe (PrecompiledCache Abs))
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Maybe (PrecompiledCache Abs)
-> RIO env (Maybe (PrecompiledCache Abs))
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (PrecompiledCache Abs)
forall a. Maybe a
Nothing) ((PrecompiledCache Abs -> Maybe (PrecompiledCache Abs))
-> RIO env (PrecompiledCache Abs)
-> RIO env (Maybe (PrecompiledCache Abs))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap PrecompiledCache Abs -> Maybe (PrecompiledCache Abs)
forall a. a -> Maybe a
Just (RIO env (PrecompiledCache Abs)
-> RIO env (Maybe (PrecompiledCache Abs)))
-> (PrecompiledCache Rel -> RIO env (PrecompiledCache Abs))
-> PrecompiledCache Rel
-> RIO env (Maybe (PrecompiledCache Abs))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PrecompiledCache Rel -> RIO env (PrecompiledCache Abs)
mkAbs) Maybe (PrecompiledCache Rel)
mcache
where
mkAbs :: PrecompiledCache Rel -> RIO env (PrecompiledCache Abs)
mkAbs :: PrecompiledCache Rel -> RIO env (PrecompiledCache Abs)
mkAbs PrecompiledCache Rel
pc0 = do
Path Abs Dir
stackRoot <- Getting (Path Abs Dir) env (Path Abs Dir) -> RIO env (Path Abs Dir)
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (Path Abs Dir) env (Path Abs Dir)
forall s. HasConfig s => Lens' s (Path Abs Dir)
stackRootL
let mkAbs' :: Path Rel t -> Path Abs t
mkAbs' = (Path Abs Dir
stackRoot Path Abs Dir -> Path Rel t -> Path Abs t
forall b t. Path b Dir -> Path Rel t -> Path b t
</>)
PrecompiledCache Abs -> RIO env (PrecompiledCache Abs)
forall (m :: * -> *) a. Monad m => a -> m a
return PrecompiledCache :: forall base.
Maybe (Path base File)
-> [Path base File] -> [Path base File] -> PrecompiledCache base
PrecompiledCache
{ pcLibrary :: Maybe (Path Abs File)
pcLibrary = Path Rel File -> Path Abs File
forall t. Path Rel t -> Path Abs t
mkAbs' (Path Rel File -> Path Abs File)
-> Maybe (Path Rel File) -> Maybe (Path Abs File)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PrecompiledCache Rel -> Maybe (Path Rel File)
forall base. PrecompiledCache base -> Maybe (Path base File)
pcLibrary PrecompiledCache Rel
pc0
, pcSubLibs :: [Path Abs File]
pcSubLibs = Path Rel File -> Path Abs File
forall t. Path Rel t -> Path Abs t
mkAbs' (Path Rel File -> Path Abs File)
-> [Path Rel File] -> [Path Abs File]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PrecompiledCache Rel -> [Path Rel File]
forall base. PrecompiledCache base -> [Path base File]
pcSubLibs PrecompiledCache Rel
pc0
, pcExes :: [Path Abs File]
pcExes = Path Rel File -> Path Abs File
forall t. Path Rel t -> Path Abs t
mkAbs' (Path Rel File -> Path Abs File)
-> [Path Rel File] -> [Path Abs File]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PrecompiledCache Rel -> [Path Rel File]
forall base. PrecompiledCache base -> [Path base File]
pcExes PrecompiledCache Rel
pc0
}