    --------------------------------------------------------------------------------
    {-# LANGUAGE CPP                        #-}
    {-# LANGUAGE DeriveDataTypeable         #-}
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    module Hakyll.Core.Provider.Internal
        ( ResourceInfo (..)
        , Provider (..)
        , newProvider

        , resourceList
        , resourceExists

        , resourceFilePath
        , resourceString
        , resourceLBS

        , resourceModified
        , resourceModificationTime
        ) where

    --------------------------------------------------------------------------------
    import           Control.DeepSeq        (NFData (..), deepseq)
    import           Control.Monad          (forM)
    import           Data.Binary            (Binary (..))
    import qualified Data.ByteString.Lazy   as BL
    import           Data.Map               (Map)
    import qualified Data.Map               as M
    import           Data.Maybe             (fromMaybe)
    import           Data.Set               (Set)
    import qualified Data.Set               as S
    import           Data.Time              (Day (..), UTCTime (..))
    import           Data.Typeable          (Typeable)
    import           System.Directory       (getModificationTime)
    import           System.FilePath        (addExtension, (</>))

    --------------------------------------------------------------------------------
    #if !MIN_VERSION_directory(1,2,0)
    import           Data.Time              (readTime)
    import           System.Locale          (defaultTimeLocale)
    import           System.Time            (formatCalendarTime, toCalendarTime)
    #endif

    --------------------------------------------------------------------------------
    import           Hakyll.Core.Identifier
    import           Hakyll.Core.Store      (Store)
    import qualified Hakyll.Core.Store      as Store
    import           Hakyll.Core.Util.File

    --------------------------------------------------------------------------------
    -- | Because UTCTime doesn't have a Binary instance...
    newtype BinaryTime = BinaryTime {BinaryTime -> UTCTime
    unBinaryTime :: UTCTime}
        deriving (BinaryTime -> BinaryTime -> Bool
    (BinaryTime -> BinaryTime -> Bool)
    -> (BinaryTime -> BinaryTime -> Bool) -> Eq BinaryTime
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: BinaryTime -> BinaryTime -> Bool
    $c/= :: BinaryTime -> BinaryTime -> Bool
    == :: BinaryTime -> BinaryTime -> Bool
    $c== :: BinaryTime -> BinaryTime -> Bool
    Eq, BinaryTime -> ()
    (BinaryTime -> ()) -> NFData BinaryTime
    forall a. (a -> ()) -> NFData a
    rnf :: BinaryTime -> ()
    $crnf :: BinaryTime -> ()
    NFData, Eq BinaryTime
    Eq BinaryTime =>
    (BinaryTime -> BinaryTime -> Ordering)
    -> (BinaryTime -> BinaryTime -> Bool)
    -> (BinaryTime -> BinaryTime -> Bool)
    -> (BinaryTime -> BinaryTime -> Bool)
    -> (BinaryTime -> BinaryTime -> Bool)
    -> (BinaryTime -> BinaryTime -> BinaryTime)
    -> (BinaryTime -> BinaryTime -> BinaryTime)
    -> Ord BinaryTime
    BinaryTime -> BinaryTime -> Bool
    BinaryTime -> BinaryTime -> Ordering
    BinaryTime -> BinaryTime -> BinaryTime
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    min :: BinaryTime -> BinaryTime -> BinaryTime
    $cmin :: BinaryTime -> BinaryTime -> BinaryTime
    max :: BinaryTime -> BinaryTime -> BinaryTime
    $cmax :: BinaryTime -> BinaryTime -> BinaryTime
    >= :: BinaryTime -> BinaryTime -> Bool
    $c>= :: BinaryTime -> BinaryTime -> Bool
    > :: BinaryTime -> BinaryTime -> Bool
    $c> :: BinaryTime -> BinaryTime -> Bool
    <= :: BinaryTime -> BinaryTime -> Bool
    $c<= :: BinaryTime -> BinaryTime -> Bool
    < :: BinaryTime -> BinaryTime -> Bool
    $c< :: BinaryTime -> BinaryTime -> Bool
    compare :: BinaryTime -> BinaryTime -> Ordering
    $ccompare :: BinaryTime -> BinaryTime -> Ordering
    $cp1Ord :: Eq BinaryTime
    Ord, Int -> BinaryTime -> ShowS
    [BinaryTime] -> ShowS
    BinaryTime -> String
    (Int -> BinaryTime -> ShowS)
    -> (BinaryTime -> String)
    -> ([BinaryTime] -> ShowS)
    -> Show BinaryTime
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [BinaryTime] -> ShowS
    $cshowList :: [BinaryTime] -> ShowS
    show :: BinaryTime -> String
    $cshow :: BinaryTime -> String
    showsPrec :: Int -> BinaryTime -> ShowS
    $cshowsPrec :: Int -> BinaryTime -> ShowS
    Show, Typeable)

    --------------------------------------------------------------------------------
    instance Binary BinaryTime where
        put :: BinaryTime -> Put
    put (BinaryTime (UTCTime (ModifiedJulianDay d :: Integer
    d) dt :: DiffTime
    dt)) =
            Integer -> Put
    forall t. Binary t => t -> Put
    put Integer
    d Put -> Put -> Put
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Rational -> Put
    forall t. Binary t => t -> Put
    put (DiffTime -> Rational
    forall a. Real a => a -> Rational
    toRational DiffTime
    dt)

        get :: Get BinaryTime
    get = (UTCTime -> BinaryTime) -> Get UTCTime -> Get BinaryTime
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap UTCTime -> BinaryTime
    BinaryTime (Get UTCTime -> Get BinaryTime) -> Get UTCTime -> Get BinaryTime
    forall a b. (a -> b) -> a -> b
    $ Day -> DiffTime -> UTCTime
    UTCTime
            (Day -> DiffTime -> UTCTime)
    -> Get Day -> Get (DiffTime -> UTCTime)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Integer -> Day
    ModifiedJulianDay (Integer -> Day) -> Get Integer -> Get Day
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Get Integer
    forall t. Binary t => Get t
    get)
            Get (DiffTime -> UTCTime) -> Get DiffTime -> Get UTCTime
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> (Rational -> DiffTime
    forall a. Fractional a => Rational -> a
    fromRational (Rational -> DiffTime) -> Get Rational -> Get DiffTime
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Get Rational
    forall t. Binary t => Get t
    get)

    --------------------------------------------------------------------------------
    data ResourceInfo = ResourceInfo
        { ResourceInfo -> BinaryTime
    resourceInfoModified :: BinaryTime
        , ResourceInfo -> Maybe Identifier
    resourceInfoMetadata :: Maybe Identifier
        } deriving (Int -> ResourceInfo -> ShowS
    [ResourceInfo] -> ShowS
    ResourceInfo -> String
    (Int -> ResourceInfo -> ShowS)
    -> (ResourceInfo -> String)
    -> ([ResourceInfo] -> ShowS)
    -> Show ResourceInfo
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [ResourceInfo] -> ShowS
    $cshowList :: [ResourceInfo] -> ShowS
    show :: ResourceInfo -> String
    $cshow :: ResourceInfo -> String
    showsPrec :: Int -> ResourceInfo -> ShowS
    $cshowsPrec :: Int -> ResourceInfo -> ShowS
    Show, Typeable)

    --------------------------------------------------------------------------------
    instance Binary ResourceInfo where
        put :: ResourceInfo -> Put
    put (ResourceInfo mtime :: BinaryTime
    mtime meta :: Maybe Identifier
    meta) = BinaryTime -> Put
    forall t. Binary t => t -> Put
    put BinaryTime
    mtime Put -> Put -> Put
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Maybe Identifier -> Put
    forall t. Binary t => t -> Put
    put Maybe Identifier
    meta
        get :: Get ResourceInfo
    get = BinaryTime -> Maybe Identifier -> ResourceInfo
    ResourceInfo (BinaryTime -> Maybe Identifier -> ResourceInfo)
    -> Get BinaryTime -> Get (Maybe Identifier -> ResourceInfo)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Get BinaryTime
    forall t. Binary t => Get t
    get Get (Maybe Identifier -> ResourceInfo)
    -> Get (Maybe Identifier) -> Get ResourceInfo
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Get (Maybe Identifier)
    forall t. Binary t => Get t
    get

    --------------------------------------------------------------------------------
    instance NFData ResourceInfo where
        rnf :: ResourceInfo -> ()
    rnf (ResourceInfo mtime :: BinaryTime
    mtime meta :: Maybe Identifier
    meta) = BinaryTime -> ()
    forall a. NFData a => a -> ()
    rnf BinaryTime
    mtime () -> () -> ()
    forall a b. a -> b -> b
    `seq` Maybe Identifier -> ()
    forall a. NFData a => a -> ()
    rnf Maybe Identifier
    meta () -> () -> ()
    forall a b. a -> b -> b
    `seq` ()

    --------------------------------------------------------------------------------
    -- | Responsible for retrieving and listing resources
    data Provider = Provider
        { -- Top of the provided directory
          Provider -> String
    providerDirectory :: FilePath
        , -- | A list of all files found
          Provider -> Map Identifier ResourceInfo
    providerFiles     :: Map Identifier ResourceInfo
        , -- | A list of the files from the previous run
          Provider -> Map Identifier ResourceInfo
    providerOldFiles  :: Map Identifier ResourceInfo
        , -- | Underlying persistent store for caching
          Provider -> Store
    providerStore     :: Store
        } deriving (Int -> Provider -> ShowS
    [Provider] -> ShowS
    Provider -> String
    (Int -> Provider -> ShowS)
    -> (Provider -> String) -> ([Provider] -> ShowS) -> Show Provider
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Provider] -> ShowS
    $cshowList :: [Provider] -> ShowS
    show :: Provider -> String
    $cshow :: Provider -> String
    showsPrec :: Int -> Provider -> ShowS
    $cshowsPrec :: Int -> Provider -> ShowS
    Show)

    --------------------------------------------------------------------------------
    -- | Create a resource provider
    newProvider :: Store                  -- ^ Store to use
                -> (FilePath -> IO Bool)  -- ^ Should we ignore this file?
                -> FilePath               -- ^ Search directory
                -> IO Provider            -- ^ Resulting provider
    newProvider :: Store -> (String -> IO Bool) -> String -> IO Provider
    newProvider store :: Store
    store ignore :: String -> IO Bool
    ignore directory :: String
    directory = do
        [Identifier]
    list <- (String -> Identifier) -> [String] -> [Identifier]
    forall a b. (a -> b) -> [a] -> [b]
    map String -> Identifier
    fromFilePath ([String] -> [Identifier]) -> IO [String] -> IO [Identifier]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (String -> IO Bool) -> String -> IO [String]
    getRecursiveContents String -> IO Bool
    ignore String
    directory
        let universe :: Set Identifier
    universe = [Identifier] -> Set Identifier
    forall a. Ord a => [a] -> Set a
    S.fromList [Identifier]
    list
        Map Identifier ResourceInfo
    files <- ([(Identifier, ResourceInfo)] -> Map Identifier ResourceInfo)
    -> IO [(Identifier, ResourceInfo)]
    -> IO (Map Identifier ResourceInfo)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Map Identifier ResourceInfo -> Map Identifier ResourceInfo
    maxmtime (Map Identifier ResourceInfo -> Map Identifier ResourceInfo)
    -> ([(Identifier, ResourceInfo)] -> Map Identifier ResourceInfo)
    -> [(Identifier, ResourceInfo)]
    -> Map Identifier ResourceInfo
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [(Identifier, ResourceInfo)] -> Map Identifier ResourceInfo
    forall k a. Ord k => [(k, a)] -> Map k a
    M.fromList) (IO [(Identifier, ResourceInfo)]
     -> IO (Map Identifier ResourceInfo))
    -> IO [(Identifier, ResourceInfo)]
    -> IO (Map Identifier ResourceInfo)
    forall a b. (a -> b) -> a -> b
    $ [Identifier]
    -> (Identifier -> IO (Identifier, ResourceInfo))
    -> IO [(Identifier, ResourceInfo)]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    t a -> (a -> m b) -> m (t b)
    forM [Identifier]
    list ((Identifier -> IO (Identifier, ResourceInfo))
     -> IO [(Identifier, ResourceInfo)])
    -> (Identifier -> IO (Identifier, ResourceInfo))
    -> IO [(Identifier, ResourceInfo)]
    forall a b. (a -> b) -> a -> b
    $ \identifier :: Identifier
    identifier -> do
            ResourceInfo
    rInfo <- String -> Set Identifier -> Identifier -> IO ResourceInfo
    getResourceInfo String
    directory Set Identifier
    universe Identifier
    identifier
            (Identifier, ResourceInfo) -> IO (Identifier, ResourceInfo)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Identifier
    identifier, ResourceInfo
    rInfo)

        -- Get the old files from the store, and then immediately replace them by
        -- the new files.
        Map Identifier ResourceInfo
    oldFiles <- Map Identifier ResourceInfo
    -> Maybe (Map Identifier ResourceInfo)
    -> Map Identifier ResourceInfo
    forall a. a -> Maybe a -> a
    fromMaybe Map Identifier ResourceInfo
    forall a. Monoid a => a
    mempty (Maybe (Map Identifier ResourceInfo)
     -> Map Identifier ResourceInfo)
    -> (Result (Map Identifier ResourceInfo)
        -> Maybe (Map Identifier ResourceInfo))
    -> Result (Map Identifier ResourceInfo)
    -> Map Identifier ResourceInfo
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Result (Map Identifier ResourceInfo)
    -> Maybe (Map Identifier ResourceInfo)
    forall a. Result a -> Maybe a
    Store.toMaybe (Result (Map Identifier ResourceInfo)
     -> Map Identifier ResourceInfo)
    -> IO (Result (Map Identifier ResourceInfo))
    -> IO (Map Identifier ResourceInfo)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Store -> [String] -> IO (Result (Map Identifier ResourceInfo))
    forall a.
    (Binary a, Typeable a) =>
    Store -> [String] -> IO (Result a)
    Store.get Store
    store [String]
    oldKey
        Map Identifier ResourceInfo
    oldFiles Map Identifier ResourceInfo -> IO () -> IO ()
    forall a b. NFData a => a -> b -> b
    `deepseq` Store -> [String] -> Map Identifier ResourceInfo -> IO ()
    forall a. (Binary a, Typeable a) => Store -> [String] -> a -> IO ()
    Store.set Store
    store [String]
    oldKey Map Identifier ResourceInfo
    files

        Provider -> IO Provider
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Provider -> IO Provider) -> Provider -> IO Provider
    forall a b. (a -> b) -> a -> b
    $ String
    -> Map Identifier ResourceInfo
    -> Map Identifier ResourceInfo
    -> Store
    -> Provider
    Provider String
    directory Map Identifier ResourceInfo
    files Map Identifier ResourceInfo
    oldFiles Store
    store
      where
        oldKey :: [String]
    oldKey = ["Hakyll.Core.Provider.Internal.newProvider", "oldFiles"]

        -- Update modified if metadata is modified
        maxmtime :: Map Identifier ResourceInfo -> Map Identifier ResourceInfo
    maxmtime files :: Map Identifier ResourceInfo
    files = ((ResourceInfo -> ResourceInfo)
     -> Map Identifier ResourceInfo -> Map Identifier ResourceInfo)
    -> Map Identifier ResourceInfo
    -> (ResourceInfo -> ResourceInfo)
    -> Map Identifier ResourceInfo
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip (ResourceInfo -> ResourceInfo)
    -> Map Identifier ResourceInfo -> Map Identifier ResourceInfo
    forall a b k. (a -> b) -> Map k a -> Map k b
    M.map Map Identifier ResourceInfo
    files ((ResourceInfo -> ResourceInfo) -> Map Identifier ResourceInfo)
    -> (ResourceInfo -> ResourceInfo) -> Map Identifier ResourceInfo
    forall a b. (a -> b) -> a -> b
    $ \rInfo :: ResourceInfo
    rInfo@(ResourceInfo mtime :: BinaryTime
    mtime meta :: Maybe Identifier
    meta) ->
            let metaMod :: Maybe BinaryTime
    metaMod = (ResourceInfo -> BinaryTime)
    -> Maybe ResourceInfo -> Maybe BinaryTime
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ResourceInfo -> BinaryTime
    resourceInfoModified (Maybe ResourceInfo -> Maybe BinaryTime)
    -> Maybe ResourceInfo -> Maybe BinaryTime
    forall a b. (a -> b) -> a -> b
    $ Maybe Identifier
    meta Maybe Identifier
    -> (Identifier -> Maybe ResourceInfo) -> Maybe ResourceInfo
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (Identifier -> Map Identifier ResourceInfo -> Maybe ResourceInfo)
    -> Map Identifier ResourceInfo -> Identifier -> Maybe ResourceInfo
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip Identifier -> Map Identifier ResourceInfo -> Maybe ResourceInfo
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup Map Identifier ResourceInfo
    files
            in ResourceInfo
    rInfo {resourceInfoModified :: BinaryTime
    resourceInfoModified = BinaryTime
    -> (BinaryTime -> BinaryTime) -> Maybe BinaryTime -> BinaryTime
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe BinaryTime
    mtime (BinaryTime -> BinaryTime -> BinaryTime
    forall a. Ord a => a -> a -> a
    max BinaryTime
    mtime) Maybe BinaryTime
    metaMod}

    --------------------------------------------------------------------------------
    getResourceInfo :: FilePath -> Set Identifier -> Identifier -> IO ResourceInfo
    getResourceInfo :: String -> Set Identifier -> Identifier -> IO ResourceInfo
    getResourceInfo directory :: String
    directory universe :: Set Identifier
    universe identifier :: Identifier
    identifier = do
        UTCTime
    mtime <- String -> IO UTCTime
    fileModificationTime (String -> IO UTCTime) -> String -> IO UTCTime
    forall a b. (a -> b) -> a -> b
    $ String
    directory String -> ShowS
    </> Identifier -> String
    toFilePath Identifier
    identifier
        ResourceInfo -> IO ResourceInfo
    forall (m :: * -> *) a. Monad m => a -> m a
    return (ResourceInfo -> IO ResourceInfo)
    -> ResourceInfo -> IO ResourceInfo
    forall a b. (a -> b) -> a -> b
    $ BinaryTime -> Maybe Identifier -> ResourceInfo
    ResourceInfo (UTCTime -> BinaryTime
    BinaryTime UTCTime
    mtime) (Maybe Identifier -> ResourceInfo)
    -> Maybe Identifier -> ResourceInfo
    forall a b. (a -> b) -> a -> b
    $
            if Identifier
    mdRsc Identifier -> Set Identifier -> Bool
    forall a. Ord a => a -> Set a -> Bool
    `S.member` Set Identifier
    universe then Identifier -> Maybe Identifier
    forall a. a -> Maybe a
    Just Identifier
    mdRsc else Maybe Identifier
    forall a. Maybe a
    Nothing
      where
        mdRsc :: Identifier
    mdRsc = String -> Identifier
    fromFilePath (String -> Identifier) -> String -> Identifier
    forall a b. (a -> b) -> a -> b
    $ (String -> ShowS) -> String -> ShowS
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip String -> ShowS
    addExtension "metadata" ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $ Identifier -> String
    toFilePath Identifier
    identifier

    --------------------------------------------------------------------------------
    resourceList :: Provider -> [Identifier]
    resourceList :: Provider -> [Identifier]
    resourceList = Map Identifier ResourceInfo -> [Identifier]
    forall k a. Map k a -> [k]
    M.keys (Map Identifier ResourceInfo -> [Identifier])
    -> (Provider -> Map Identifier ResourceInfo)
    -> Provider
    -> [Identifier]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Provider -> Map Identifier ResourceInfo
    providerFiles

    --------------------------------------------------------------------------------
    -- | Check if a given resource exists
    resourceExists :: Provider -> Identifier -> Bool
    resourceExists :: Provider -> Identifier -> Bool
    resourceExists provider :: Provider
    provider =
        (Identifier -> Map Identifier ResourceInfo -> Bool
    forall k a. Ord k => k -> Map k a -> Bool
    `M.member` Provider -> Map Identifier ResourceInfo
    providerFiles Provider
    provider) (Identifier -> Bool)
    -> (Identifier -> Identifier) -> Identifier -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Maybe String -> Identifier -> Identifier
    setVersion Maybe String
    forall a. Maybe a
    Nothing

    --------------------------------------------------------------------------------
    resourceFilePath :: Provider -> Identifier -> FilePath
    resourceFilePath :: Provider -> Identifier -> String
    resourceFilePath p :: Provider
    p i :: Identifier
    i = Provider -> String
    providerDirectory Provider
    p String -> ShowS
    </> Identifier -> String
    toFilePath Identifier
    i

    --------------------------------------------------------------------------------
    -- | Get the raw body of a resource as string
    resourceString :: Provider -> Identifier -> IO String
    resourceString :: Provider -> Identifier -> IO String
    resourceString p :: Provider
    p i :: Identifier
    i = String -> IO String
    readFile (String -> IO String) -> String -> IO String
    forall a b. (a -> b) -> a -> b
    $ Provider -> Identifier -> String
    resourceFilePath Provider
    p Identifier
    i

    --------------------------------------------------------------------------------
    -- | Get the raw body of a resource of a lazy bytestring
    resourceLBS :: Provider -> Identifier -> IO BL.ByteString
    resourceLBS :: Provider -> Identifier -> IO ByteString
    resourceLBS p :: Provider
    p i :: Identifier
    i = String -> IO ByteString
    BL.readFile (String -> IO ByteString) -> String -> IO ByteString
    forall a b. (a -> b) -> a -> b
    $ Provider -> Identifier -> String
    resourceFilePath Provider
    p Identifier
    i

    --------------------------------------------------------------------------------
    -- | A resource is modified if it or its metadata has changed
    resourceModified :: Provider -> Identifier -> Bool
    resourceModified :: Provider -> Identifier -> Bool
    resourceModified p :: Provider
    p r :: Identifier
    r = case (Maybe ResourceInfo
    ri, Maybe ResourceInfo
    oldRi) of
        (Nothing, _)      -> Bool
    False
        (Just _, Nothing) -> Bool
    True
        (Just n :: ResourceInfo
    n, Just o :: ResourceInfo
    o)  ->
            ResourceInfo -> BinaryTime
    resourceInfoModified ResourceInfo
    n BinaryTime -> BinaryTime -> Bool
    forall a. Ord a => a -> a -> Bool
    >  ResourceInfo -> BinaryTime
    resourceInfoModified ResourceInfo
    o Bool -> Bool -> Bool
    ||
            ResourceInfo -> Maybe Identifier
    resourceInfoMetadata ResourceInfo
    n Maybe Identifier -> Maybe Identifier -> Bool
    forall a. Eq a => a -> a -> Bool
    /= ResourceInfo -> Maybe Identifier
    resourceInfoMetadata ResourceInfo
    o
      where
        normal :: Identifier
    normal = Maybe String -> Identifier -> Identifier
    setVersion Maybe String
    forall a. Maybe a
    Nothing Identifier
    r
        ri :: Maybe ResourceInfo
    ri     = Identifier -> Map Identifier ResourceInfo -> Maybe ResourceInfo
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup Identifier
    normal (Provider -> Map Identifier ResourceInfo
    providerFiles Provider
    p)
        oldRi :: Maybe ResourceInfo
    oldRi  = Identifier -> Map Identifier ResourceInfo -> Maybe ResourceInfo
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup Identifier
    normal (Provider -> Map Identifier ResourceInfo
    providerOldFiles Provider
    p)

    --------------------------------------------------------------------------------
    resourceModificationTime :: Provider -> Identifier -> UTCTime
    resourceModificationTime :: Provider -> Identifier -> UTCTime
    resourceModificationTime p :: Provider
    p i :: Identifier
    i =
        case Identifier -> Map Identifier ResourceInfo -> Maybe ResourceInfo
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup (Maybe String -> Identifier -> Identifier
    setVersion Maybe String
    forall a. Maybe a
    Nothing Identifier
    i) (Provider -> Map Identifier ResourceInfo
    providerFiles Provider
    p) of
            Just ri :: ResourceInfo
    ri -> BinaryTime -> UTCTime
    unBinaryTime (BinaryTime -> UTCTime) -> BinaryTime -> UTCTime
    forall a b. (a -> b) -> a -> b
    $ ResourceInfo -> BinaryTime
    resourceInfoModified ResourceInfo
    ri
            Nothing -> String -> UTCTime
    forall a. HasCallStack => String -> a
    error (String -> UTCTime) -> String -> UTCTime
    forall a b. (a -> b) -> a -> b
    $
                "Hakyll.Core.Provider.Internal.resourceModificationTime: " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
                "resource " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Identifier -> String
    forall a. Show a => a -> String
    show Identifier
    i String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ " does not exist"

    --------------------------------------------------------------------------------
    fileModificationTime :: FilePath -> IO UTCTime
    fileModificationTime :: String -> IO UTCTime
    fileModificationTime fp :: String
    fp = do
    #if MIN_VERSION_directory(1,2,0)
        String -> IO UTCTime
    getModificationTime String
    fp
    #else
        ct <- toCalendarTime =<< getModificationTime fp
        let str = formatCalendarTime defaultTimeLocale "%s" ct
        return $ readTime defaultTimeLocale "%s" str
    #endif