packages feed

shake-0.1.4: Development/Shake/FileTime.hs

{-# LANGUAGE MultiParamTypeClasses, GeneralizedNewtypeDeriving, DeriveDataTypeable #-}

module Development.Shake.FileTime(
    FileTime, sleepFileTime,
    getModTime, getModTimeError, getModTimeMaybe,
    getAccTime
    ) where

import Control.Concurrent(threadDelay)
import Control.DeepSeq
import Data.Binary
import Data.Hashable
import Data.Typeable
import System.Directory
import System.Directory.AccessTime
import System.Time


newtype FileTime = FileTime Int
    deriving (Typeable,Eq,Hashable,Binary,Show,NFData)


getModTimeMaybe :: FilePath -> IO (Maybe FileTime)
getModTimeMaybe x = do
    b <- doesFileExist x
    if b then fmap Just $ getModTime x else return Nothing


getModTimeError :: String -> FilePath -> IO FileTime
getModTimeError msg x = do
    res <- getModTimeMaybe x
    case res of
        -- Important to raise an error in IO, not return a value which will error later
        Nothing -> error $ msg ++ "\n" ++ x
        Just x -> return x


getModTime :: FilePath -> IO FileTime
getModTime x = do
    TOD t _ <- getModificationTime x
    return $ FileTime $ fromIntegral t


getAccTime :: FilePath -> IO FileTime
getAccTime x = do
    TOD t _ <- getAccessTime x
    return $ FileTime $ fromIntegral t


-- | Sleep long enough for the modification time resolution to catch up
sleepFileTime :: IO ()
sleepFileTime = threadDelay 1000000 -- 1 second