Skip to content

Commit

Permalink
Do correct path checking in precompiled cache.
Browse files Browse the repository at this point in the history
The commit ed9ccc0 changed the behavior
of the precompiled cache to store relative instead of absolute paths.
That seems to have broken the ability to properly check if a library
exists, thereby defeating precompiled caching.

The issue that discovered this is #3431, and ascribed this to extensible
snapshots. I _think_, though I'm not 100% certain, that this bug reaches
much farther than extensible snapshots, and in fact breaks all
precompiled caches.
  • Loading branch information
snoyberg committed Oct 18, 2017
1 parent 0adb224 commit 7b5bfbc
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 5 deletions.
2 changes: 2 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ Bug fixes:
* `stack build --only-dependencies` no longer builds local project packages
that are depended on. See
[#3476](https://github.com/commercialhaskell/stack/issues/3476).
* Properly handle relative paths stored in the precompiled cache files. See
[#3431](https://github.com/commercialhaskell/stack/issues/3431).


## 1.5.1
Expand Down
28 changes: 23 additions & 5 deletions src/Stack/Build/Cache.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ module Stack.Build.Cache

import Stack.Prelude
import Crypto.Hash (hashWith, SHA256(..))
import Control.Monad.Trans.Maybe
import qualified Data.ByteArray as Mem (convert)
import qualified Data.ByteString.Base64.URL as B64URL
import qualified Data.ByteString as B
Expand All @@ -55,6 +56,7 @@ import Stack.Types.GhcPkgId
import Stack.Types.Package
import Stack.Types.PackageIdentifier
import Stack.Types.Version
import qualified System.FilePath as FP

-- | Directory containing files to mark an executable as installed
exeInstalledDir :: (MonadReader env m, HasEnvConfig env, MonadThrow m)
Expand Down Expand Up @@ -313,11 +315,27 @@ writePrecompiledCache baseConfigOpts loc copts depIDs mghcPkgId exes = do

-- | Check the cache for a precompiled package matching the given
-- configuration.
readPrecompiledCache :: (MonadThrow m, MonadReader env m, HasEnvConfig env, MonadUnliftIO m, MonadLogger m)
readPrecompiledCache :: forall env. HasEnvConfig env
=> PackageLocationIndex FilePath -- ^ target package
-> ConfigureOpts
-> Set GhcPkgId -- ^ dependencies
-> m (Maybe PrecompiledCache)
readPrecompiledCache loc copts depIDs =
precompiledCacheFile loc copts depIDs >>=
maybe (return Nothing) $(versionedDecodeFile precompiledCacheVC)
-> RIO env (Maybe PrecompiledCache)
readPrecompiledCache loc copts depIDs = runMaybeT $
MaybeT (precompiledCacheFile loc copts depIDs) >>=
MaybeT . $(versionedDecodeFile precompiledCacheVC) >>=
lift . mkAbs
where
-- Since commit ed9ccc08f327bad68dd2d09a1851ce0d055c0422,
-- pcLibrary paths are stored as relative to the stack
-- root. Therefore, we need to prepend the stack root when
-- checking that the file exists. For the older cached paths, the
-- file will contain an absolute path, which will make `stackRoot
-- </>` a no-op.
mkAbs :: PrecompiledCache -> RIO env PrecompiledCache
mkAbs pc0 = do
stackRoot <- view stackRootL
let mkAbs' = (toFilePath stackRoot FP.</>)
return PrecompiledCache
{ pcLibrary = mkAbs' <$> pcLibrary pc0
, pcExes = mkAbs' <$> pcExes pc0
}

0 comments on commit 7b5bfbc

Please sign in to comment.