readPrecompiledCache :: (MonadThrow m, MonadReader env m, HasEnvConfig env, MonadIO m, MonadLogger m, MonadBaseControl IO m)
                     => PackageIdentifier -- ^ target package
                     -> ConfigureOpts
                     -> Set GhcPkgId -- ^ dependencies
                     -> m (Maybe PrecompiledCache)
readPrecompiledCache pkgident copts depIDs = do
    ec <- asks getEnvConfig
    let toAbsPath path = do
          if FilePath.isAbsolute path
              then path -- Only older version store absolute path
              else toFilePath (getStackRoot ec) FilePath.</> path
    let toAbsPC pc =
            PrecompiledCache
                  { pcLibrary = fmap toAbsPath (pcLibrary pc)
                  , pcExes = map toAbsPath (pcExes pc)
                  }

    (file, getOldFile) <- precompiledCacheFile pkgident copts depIDs
    mres <- $(versionedDecodeFile precompiledCacheVC) file
    case mres of
        Just res -> return (Just $ toAbsPC res)
        Nothing -> do
            -- Fallback on trying the old binary format.
            oldFile <- getOldFile
            mpc <- fmap (fmap toAbsPC) $ binaryDecodeFileOrFailDeep oldFile
            -- Write out file in new format. Keep old file around for
            -- the benefit of older stack versions.
            forM_ mpc ($(versionedEncodeFile precompiledCacheVC) file)
            return mpc

-- | Ensure that there are no lurking exceptions deep inside the parsed
-- value... because that happens unfortunately. See
-- https://github.com/commercialhaskell/stack/issues/554
readPrecompiledCache :: (MonadThrow m, MonadReader env m, HasEnvConfig env, MonadIO m, MonadLogger m, MonadBaseControl IO m)
                     => PackageIdentifier -- ^ target package
                     -> ConfigureOpts
                     -> Set GhcPkgId -- ^ dependencies
                     -> m (Maybe PrecompiledCache)
readPrecompiledCache pkgident copts depIDs = do
    ec <- asks getEnvConfig
    let toAbsPath path = do
          if FilePath.isAbsolute path
              then path -- Only older version store absolute path
              else toFilePath (getStackRoot ec) FilePath.</> path
    let toAbsPC pc =
            PrecompiledCache
                  { pcLibrary = fmap toAbsPath (pcLibrary pc)
                  , pcExes = map toAbsPath (pcExes pc)
                  }

    (file, getOldFile) <- precompiledCacheFile pkgident copts depIDs
    mres <- $(versionedDecodeFile precompiledCacheVC) file
    case mres of
        Just res -> return (Just $ toAbsPC res)
        Nothing -> do
            -- Fallback on trying the old binary format.
            oldFile <- getOldFile
            mpc <- fmap (fmap toAbsPC) $ binaryDecodeFileOrFailDeep oldFile
            -- Write out file in new format. Keep old file around for
            -- the benefit of older stack versions.
            forM_ mpc ($(versionedEncodeFile precompiledCacheVC) file)
            return mpc

-- | Ensure that there are no lurking exceptions deep inside the parsed
-- value... because that happens unfortunately. See
-- https://github.com/commercialhaskell/stack/issues/554
readPrecompiledCache pkgident copts depIDs = do
    ec <- asks getEnvConfig
    let toAbsPath path = do
          if FilePath.isAbsolute path
              then path -- Only older version store absolute path
              else toFilePath (getStackRoot ec) FilePath.</> path
    let toAbsPC pc =
            PrecompiledCache
                  { pcLibrary = fmap toAbsPath (pcLibrary pc)
                  , pcExes = map toAbsPath (pcExes pc)
                  }

    (file, getOldFile) <- precompiledCacheFile pkgident copts depIDs
    mres <- $(versionedDecodeFile precompiledCacheVC) file
    case mres of
        Just res -> return (Just $ toAbsPC res)
        Nothing -> do
            -- Fallback on trying the old binary format.
            oldFile <- getOldFile
            mpc <- fmap (fmap toAbsPC) $ binaryDecodeFileOrFailDeep oldFile
            -- Write out file in new format. Keep old file around for
            -- the benefit of older stack versions.
            forM_ mpc ($(versionedEncodeFile precompiledCacheVC) file)
            return mpc

-- | Ensure that there are no lurking exceptions deep inside the parsed
-- value... because that happens unfortunately. See
-- https://github.com/commercialhaskell/stack/issues/554