@@ -19,16 +19,13 @@ module Stack.Build.Source
1919
2020import Stack.Prelude
2121import qualified Pantry.SHA256 as SHA256
22- import qualified Data.ByteString as S
2322import Data.ByteString.Builder (toLazyByteString )
2423import Conduit (ZipSink (.. ), withSourceFile )
25- import qualified Data.Conduit.List as CL
2624import qualified Distribution.PackageDescription as C
2725import Data.List
2826import qualified Data.Map as Map
2927import qualified Data.Map.Strict as M
3028import qualified Data.Set as Set
31- import Foreign.C.Types (CTime )
3229import Stack.Build.Cache
3330import Stack.Build.Haddock (shouldHaddockDeps )
3431import Stack.Build.Target
@@ -41,7 +38,6 @@ import Stack.Types.Package
4138import Stack.Types.SourceMap
4239import System.FilePath (takeFileName )
4340import System.IO.Error (isDoesNotExistError )
44- import System.PosixCompat.Files (modificationTime , getFileStatus )
4541
4642-- | loads and returns project packages
4743projectLocalPackages :: HasEnvConfig env
@@ -406,46 +402,38 @@ checkBuildCache :: forall m. (MonadIO m)
406402 -> m (Set FilePath , Map FilePath FileCacheInfo )
407403checkBuildCache oldCache files = do
408404 fileTimes <- liftM Map. fromList $ forM files $ \ fp -> do
409- mmodTime <- liftIO (getModTimeMaybe (toFilePath fp))
410- return (toFilePath fp, mmodTime )
405+ mdigest <- liftIO (getFileDigestMaybe (toFilePath fp))
406+ return (toFilePath fp, mdigest )
411407 liftM (mconcat . Map. elems) $ sequence $
412408 Map. mergeWithKey
413- (\ fp mmodTime fci -> Just (go fp mmodTime (Just fci)))
414- (Map. mapWithKey (\ fp mmodTime -> go fp mmodTime Nothing ))
409+ (\ fp mdigest fci -> Just (go fp mdigest (Just fci)))
410+ (Map. mapWithKey (\ fp mdigest -> go fp mdigest Nothing ))
415411 (Map. mapWithKey (\ fp fci -> go fp Nothing (Just fci)))
416412 fileTimes
417413 oldCache
418414 where
419- go :: FilePath -> Maybe CTime -> Maybe FileCacheInfo -> m (Set FilePath , Map FilePath FileCacheInfo )
415+ go :: FilePath -> Maybe SHA256 -> Maybe FileCacheInfo -> m (Set FilePath , Map FilePath FileCacheInfo )
420416 -- Filter out the cabal_macros file to avoid spurious recompilations
421417 go fp _ _ | takeFileName fp == " cabal_macros.h" = return (Set. empty, Map. empty)
422418 -- 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)
425- | 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)
419+ go fp (Just digest') (Just fci)
420+ | fciHash fci == digest' = return (Set. empty, Map. singleton fp fci)
421+ | otherwise = return (Set. singleton fp, Map. singleton fp $ FileCacheInfo digest')
432422 -- Missing file. Add it to dirty files, but no FileCacheInfo.
433423 go fp Nothing _ = return (Set. singleton fp, Map. empty)
434424 -- Missing cache. Add it to dirty files and compute FileCacheInfo.
435- go fp (Just modTime') Nothing = do
436- newFci <- calcFci modTime' fp
437- return (Set. singleton fp, Map. singleton fp newFci)
425+ go fp (Just digest') Nothing =
426+ return (Set. singleton fp, Map. singleton fp $ FileCacheInfo digest')
438427
439428-- | Returns entries to add to the build cache for any newly found unlisted modules
440429addUnlistedToBuildCache
441430 :: HasEnvConfig env
442- => CTime
443- -> Package
431+ => Package
444432 -> Path Abs File
445433 -> Set NamedComponent
446434 -> Map NamedComponent (Map FilePath a )
447435 -> RIO env (Map NamedComponent [Map FilePath FileCacheInfo ], [PackageWarning ])
448- addUnlistedToBuildCache preBuildTime pkg cabalFP nonLibComponents buildCaches = do
436+ addUnlistedToBuildCache pkg cabalFP nonLibComponents buildCaches = do
449437 (componentFiles, warnings) <- getPackageFilesForTargets pkg cabalFP nonLibComponents
450438 results <- forM (M. toList componentFiles) $ \ (component, files) -> do
451439 let buildCache = M. findWithDefault M. empty component buildCaches
@@ -457,13 +445,10 @@ addUnlistedToBuildCache preBuildTime pkg cabalFP nonLibComponents buildCaches =
457445 return (M. fromList (map fst results), concatMap snd results)
458446 where
459447 addFileToCache fp = do
460- mmodTime <- getModTimeMaybe fp
461- case mmodTime of
448+ mdigest <- getFileDigestMaybe fp
449+ case mdigest of
462450 Nothing -> return Map. empty
463- Just modTime' ->
464- if modTime' < preBuildTime
465- then Map. singleton fp <$> calcFci modTime' fp
466- else return Map. empty
451+ Just digest' -> return . Map. singleton fp $ FileCacheInfo digest'
467452
468453-- | Gets list of Paths for files relevant to a set of components in a package.
469454-- Note that the library component, if any, is always automatically added to the
@@ -484,34 +469,18 @@ getPackageFilesForTargets pkg cabalFP nonLibComponents = do
484469 M. filterWithKey (\ component _ -> component `elem` components) compFiles
485470 return (componentsFiles, warnings)
486471
487- -- | Get file modification time , if it exists.
488- getModTimeMaybe :: MonadIO m => FilePath -> m (Maybe CTime )
489- getModTimeMaybe fp =
472+ -- | Get file digest , if it exists
473+ getFileDigestMaybe :: MonadIO m => FilePath -> m (Maybe SHA256 )
474+ getFileDigestMaybe fp = do
490475 liftIO
491476 (catch
492- (liftM
493- (Just . modificationTime)
494- (getFileStatus fp))
477+ (liftM Just . withSourceFile fp $ getDigest)
495478 (\ e ->
496479 if isDoesNotExistError e
497480 then return Nothing
498481 else throwM e))
499-
500- -- | 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- }
482+ where
483+ getDigest src = runConduit $ src .| getZipSink (ZipSink SHA256. sinkHash)
515484
516485-- | Get 'PackageConfig' for package given its name.
517486getPackageConfig
0 commit comments