@@ -28,7 +28,6 @@ import Data.List
2828import qualified Data.Map as Map
2929import qualified Data.Map.Strict as M
3030import qualified Data.Set as Set
31- import Foreign.C.Types (CTime )
3231import Stack.Build.Cache
3332import Stack.Build.Haddock (shouldHaddockDeps )
3433import Stack.Build.Target
@@ -406,46 +405,41 @@ checkBuildCache :: forall m. (MonadIO m)
406405 -> m (Set FilePath , Map FilePath FileCacheInfo )
407406checkBuildCache oldCache files = do
408407 fileTimes <- liftM Map. fromList $ forM files $ \ fp -> do
409- mmodTime <- liftIO (getModTimeMaybe (toFilePath fp))
410- return (toFilePath fp, mmodTime )
408+ mdigest <- liftIO (getFileDigestMaybe (toFilePath fp))
409+ return (toFilePath fp, mdigest )
411410 liftM (mconcat . Map. elems) $ sequence $
412411 Map. mergeWithKey
413- (\ fp mmodTime fci -> Just (go fp mmodTime (Just fci)))
414- (Map. mapWithKey (\ fp mmodTime -> go fp mmodTime Nothing ))
412+ (\ fp mdigest fci -> Just (go fp mdigest (Just fci)))
413+ (Map. mapWithKey (\ fp mdigest -> go fp mdigest Nothing ))
415414 (Map. mapWithKey (\ fp fci -> go fp Nothing (Just fci)))
416415 fileTimes
417416 oldCache
418417 where
419- go :: FilePath -> Maybe CTime -> Maybe FileCacheInfo -> m (Set FilePath , Map FilePath FileCacheInfo )
418+ go :: FilePath -> Maybe ( FileSize , SHA256 ) -> Maybe FileCacheInfo -> m (Set FilePath , Map FilePath FileCacheInfo )
420419 -- Filter out the cabal_macros file to avoid spurious recompilations
421420 go fp _ _ | takeFileName fp == " cabal_macros.h" = return (Set. empty, Map. empty)
422421 -- Common case where it's in the cache and on the filesystem.
423- go fp (Just modTime' ) (Just fci)
424- | fciModTime fci == modTime ' = return (Set. empty, Map. singleton fp fci)
422+ go fp (Just (size, digest') ) (Just fci)
423+ | fciHash fci == digest ' = return (Set. empty, Map. singleton fp fci)
425424 | otherwise = do
426- newFci <- calcFci modTime' fp
427- let isDirty =
428- fciSize fci /= fciSize newFci ||
429- fciHash fci /= fciHash newFci
430- newDirty = if isDirty then Set. singleton fp else Set. empty
431- return (newDirty, Map. singleton fp newFci)
425+ newFci <- calcFci (size,digest') fp
426+ return (Set. singleton fp, Map. singleton fp newFci)
432427 -- Missing file. Add it to dirty files, but no FileCacheInfo.
433428 go fp Nothing _ = return (Set. singleton fp, Map. empty)
434429 -- Missing cache. Add it to dirty files and compute FileCacheInfo.
435- go fp (Just modTime' ) Nothing = do
436- newFci <- calcFci modTime' fp
430+ go fp (Just (size, digest') ) Nothing = do
431+ newFci <- calcFci (size,digest') fp
437432 return (Set. singleton fp, Map. singleton fp newFci)
438433
439434-- | Returns entries to add to the build cache for any newly found unlisted modules
440435addUnlistedToBuildCache
441436 :: HasEnvConfig env
442- => CTime
443- -> Package
437+ => Package
444438 -> Path Abs File
445439 -> Set NamedComponent
446440 -> Map NamedComponent (Map FilePath a )
447441 -> RIO env (Map NamedComponent [Map FilePath FileCacheInfo ], [PackageWarning ])
448- addUnlistedToBuildCache preBuildTime pkg cabalFP nonLibComponents buildCaches = do
442+ addUnlistedToBuildCache pkg cabalFP nonLibComponents buildCaches = do
449443 (componentFiles, warnings) <- getPackageFilesForTargets pkg cabalFP nonLibComponents
450444 results <- forM (M. toList componentFiles) $ \ (component, files) -> do
451445 let buildCache = M. findWithDefault M. empty component buildCaches
@@ -457,13 +451,10 @@ addUnlistedToBuildCache preBuildTime pkg cabalFP nonLibComponents buildCaches =
457451 return (M. fromList (map fst results), concatMap snd results)
458452 where
459453 addFileToCache fp = do
460- mmodTime <- getModTimeMaybe fp
461- case mmodTime of
454+ mdigest <- getFileDigestMaybe fp
455+ case mdigest of
462456 Nothing -> return Map. empty
463- Just modTime' ->
464- if modTime' < preBuildTime
465- then Map. singleton fp <$> calcFci modTime' fp
466- else return Map. empty
457+ Just digest' -> Map. singleton fp <$> calcFci digest' fp
467458
468459-- | Gets list of Paths for files relevant to a set of components in a package.
469460-- Note that the library component, if any, is always automatically added to the
@@ -484,34 +475,33 @@ getPackageFilesForTargets pkg cabalFP nonLibComponents = do
484475 M. filterWithKey (\ component _ -> component `elem` components) compFiles
485476 return (componentsFiles, warnings)
486477
487- -- | Get file modification time, if it exists.
488- getModTimeMaybe :: MonadIO m => FilePath -> m (Maybe CTime )
489- getModTimeMaybe fp =
478+ -- | Get file digest
479+ getFileDigestMaybe :: MonadIO m => FilePath -> m (Maybe ( FileSize , SHA256 ) )
480+ getFileDigestMaybe fp =
490481 liftIO
491482 (catch
492483 (liftM
493- (Just . modificationTime)
494- (getFileStatus fp))
484+ (\ (size, digest) -> Just (FileSize size, digest))
485+ (withSourceFile fp $ \ src -> runConduit $ src .| getZipSink
486+ ((,)
487+ <$> ZipSink (CL. fold
488+ (\ x y -> x + fromIntegral (S. length y))
489+ 0 )
490+ <*> ZipSink SHA256. sinkHash)))
495491 (\ e ->
496492 if isDoesNotExistError e
497493 then return Nothing
498494 else throwM e))
499495
500496-- | Create FileCacheInfo for a file.
501- calcFci :: MonadIO m => CTime -> FilePath -> m FileCacheInfo
502- calcFci modTime' fp = liftIO $
503- withSourceFile fp $ \ src -> do
504- (size, digest) <- runConduit $ src .| getZipSink
505- ((,)
506- <$> ZipSink (CL. fold
507- (\ x y -> x + fromIntegral (S. length y))
508- 0 )
509- <*> ZipSink SHA256. sinkHash)
510- return FileCacheInfo
511- { fciModTime = modTime'
512- , fciSize = FileSize size
513- , fciHash = digest
514- }
497+ calcFci :: MonadIO m => (FileSize ,SHA256 ) -> FilePath -> m FileCacheInfo
498+ calcFci (size, digest) fp = liftIO $ do
499+ modTime' <- fmap modificationTime $ getFileStatus fp
500+ return FileCacheInfo
501+ { fciModTime = modTime'
502+ , fciSize = size
503+ , fciHash = digest
504+ }
515505
516506-- | Get 'PackageConfig' for package given its name.
517507getPackageConfig
0 commit comments