From 015663657ceca7b168bf7d91fbc2fccc41c40904 Mon Sep 17 00:00:00 2001 From: Jasper Van der Jeugt Date: Tue, 5 Apr 2011 22:14:49 +0200 Subject: New resource module hierarchy --- src/Hakyll.hs | 6 +- src/Hakyll/Core/Compiler.hs | 11 +--- src/Hakyll/Core/Compiler/Internal.hs | 2 +- src/Hakyll/Core/Resource.hs | 14 ++++ src/Hakyll/Core/Resource/Provider.hs | 68 ++++++++++++++++++++ src/Hakyll/Core/Resource/Provider/File.hs | 30 +++++++++ src/Hakyll/Core/ResourceProvider.hs | 75 ---------------------- .../Core/ResourceProvider/FileResourceProvider.hs | 29 --------- src/Hakyll/Core/Rules.hs | 3 +- src/Hakyll/Core/Rules/Internal.hs | 3 +- src/Hakyll/Core/Run.hs | 5 +- src/Hakyll/Core/Writable/CopyFile.hs | 2 +- src/Hakyll/Web/CompressCss.hs | 2 +- src/Hakyll/Web/Page.hs | 2 +- src/Hakyll/Web/Template.hs | 2 +- 15 files changed, 130 insertions(+), 124 deletions(-) create mode 100644 src/Hakyll/Core/Resource.hs create mode 100644 src/Hakyll/Core/Resource/Provider.hs create mode 100644 src/Hakyll/Core/Resource/Provider/File.hs delete mode 100644 src/Hakyll/Core/ResourceProvider.hs delete mode 100644 src/Hakyll/Core/ResourceProvider/FileResourceProvider.hs (limited to 'src') diff --git a/src/Hakyll.hs b/src/Hakyll.hs index 5fe1f26..341bb53 100644 --- a/src/Hakyll.hs +++ b/src/Hakyll.hs @@ -5,7 +5,8 @@ module Hakyll , module Hakyll.Core.Configuration , module Hakyll.Core.Identifier , module Hakyll.Core.Identifier.Pattern - , module Hakyll.Core.ResourceProvider + , module Hakyll.Core.Resource + , module Hakyll.Core.Resource.Provider , module Hakyll.Core.Routes , module Hakyll.Core.Rules , module Hakyll.Core.UnixFilter @@ -34,7 +35,8 @@ import Hakyll.Core.Compiler import Hakyll.Core.Configuration import Hakyll.Core.Identifier import Hakyll.Core.Identifier.Pattern -import Hakyll.Core.ResourceProvider +import Hakyll.Core.Resource +import Hakyll.Core.Resource.Provider import Hakyll.Core.Routes import Hakyll.Core.Rules import Hakyll.Core.UnixFilter diff --git a/src/Hakyll/Core/Compiler.hs b/src/Hakyll/Core/Compiler.hs index 7fe1754..db51131 100644 --- a/src/Hakyll/Core/Compiler.hs +++ b/src/Hakyll/Core/Compiler.hs @@ -89,7 +89,6 @@ module Hakyll.Core.Compiler ( Compiler , runCompiler , getIdentifier - , getIdentifiers , getRoute , getRouteFor , getResourceString @@ -125,7 +124,8 @@ import Hakyll.Core.Identifier import Hakyll.Core.Identifier.Pattern import Hakyll.Core.CompiledItem import Hakyll.Core.Writable -import Hakyll.Core.ResourceProvider +import Hakyll.Core.Resource +import Hakyll.Core.Resource.Provider import Hakyll.Core.Compiler.Internal import Hakyll.Core.Store import Hakyll.Core.Rules.Internal @@ -166,13 +166,6 @@ runCompiler compiler identifier provider routes store modified logger = do getIdentifier :: Compiler a Identifier getIdentifier = fromJob $ const $ CompilerM $ compilerIdentifier <$> ask --- | Get all identifiers matching the given pattern --- -getIdentifiers :: Pattern -> Compiler a [Identifier] -getIdentifiers pattern = fromJob $ const $ CompilerM $ - matches pattern . map unResource . resourceList - . compilerResourceProvider <$> ask - -- | Get the route we are using for this item -- getRoute :: Compiler a (Maybe FilePath) diff --git a/src/Hakyll/Core/Compiler/Internal.hs b/src/Hakyll/Core/Compiler/Internal.hs index 4eef91c..1a3c4c3 100644 --- a/src/Hakyll/Core/Compiler/Internal.hs +++ b/src/Hakyll/Core/Compiler/Internal.hs @@ -26,7 +26,7 @@ import Control.Category (Category, (.), id) import Control.Arrow (Arrow, ArrowChoice, arr, first, left) import Hakyll.Core.Identifier -import Hakyll.Core.ResourceProvider +import Hakyll.Core.Resource.Provider import Hakyll.Core.Store import Hakyll.Core.Routes import Hakyll.Core.Logger diff --git a/src/Hakyll/Core/Resource.hs b/src/Hakyll/Core/Resource.hs new file mode 100644 index 0000000..d60fda9 --- /dev/null +++ b/src/Hakyll/Core/Resource.hs @@ -0,0 +1,14 @@ +-- | Module exporting the simple 'Resource' type +-- +module Hakyll.Core.Resource + ( Resource (..) + ) where + +import Hakyll.Core.Identifier + +-- | A resource +-- +-- Invariant: the resource specified by the given identifier must exist +-- +newtype Resource = Resource {unResource :: Identifier} + deriving (Eq, Show, Ord) diff --git a/src/Hakyll/Core/Resource/Provider.hs b/src/Hakyll/Core/Resource/Provider.hs new file mode 100644 index 0000000..377b029 --- /dev/null +++ b/src/Hakyll/Core/Resource/Provider.hs @@ -0,0 +1,68 @@ +-- | This module provides an API for resource providers. Resource providers +-- allow Hakyll to get content from resources; the type of resource depends on +-- the concrete instance. +-- +-- A resource is represented by the 'Resource' type. This is basically just a +-- newtype wrapper around 'Identifier' -- but it has an important effect: it +-- guarantees that a resource with this identifier can be provided by one or +-- more resource providers. +-- +-- Therefore, it is not recommended to read files directly -- you should use the +-- provided 'Resource' methods. +-- +module Hakyll.Core.Resource.Provider + ( ResourceProvider (..) + , resourceExists + , resourceDigest + , resourceModified + ) where + +import Control.Monad ((<=<)) +import Data.Word (Word8) + +import qualified Data.ByteString.Lazy as LB +import OpenSSL.Digest.ByteString.Lazy (digest) +import OpenSSL.Digest (MessageDigest (MD5)) + +import Hakyll.Core.Identifier +import Hakyll.Core.Store +import Hakyll.Core.Resource + +-- | A value responsible for retrieving and listing resources +-- +data ResourceProvider = ResourceProvider + { -- | A list of all resources this provider is able to provide + resourceList :: [Resource] + , -- | Retrieve a certain resource as string + resourceString :: Resource -> IO String + , -- | Retrieve a certain resource as lazy bytestring + resourceLazyByteString :: Resource -> IO LB.ByteString + } + +-- | Check if a given identifier has a resource +-- +resourceExists :: ResourceProvider -> Identifier -> Bool +resourceExists provider = flip elem $ map unResource $ resourceList provider + +-- | Retrieve a digest for a given resource +-- +resourceDigest :: ResourceProvider -> Resource -> IO [Word8] +resourceDigest provider = digest MD5 <=< resourceLazyByteString provider + +-- | Check if a resource was modified +-- +resourceModified :: ResourceProvider -> Resource -> Store -> IO Bool +resourceModified provider resource store = do + -- Get the latest seen digest from the store + lastDigest <- storeGet store itemName $ unResource resource + -- Calculate the digest for the resource + newDigest <- resourceDigest provider resource + -- Check digests + if Just newDigest == lastDigest + -- All is fine, not modified + then return False + -- Resource modified; store new digest + else do storeSet store itemName (unResource resource) newDigest + return True + where + itemName = "Hakyll.Core.ResourceProvider.resourceModified" diff --git a/src/Hakyll/Core/Resource/Provider/File.hs b/src/Hakyll/Core/Resource/Provider/File.hs new file mode 100644 index 0000000..a795fac --- /dev/null +++ b/src/Hakyll/Core/Resource/Provider/File.hs @@ -0,0 +1,30 @@ +-- | A concrete 'ResourceProvider' that gets it's resources from the filesystem +-- +module Hakyll.Core.Resource.Provider.File + ( fileResourceProvider + ) where + +import Control.Applicative ((<$>)) + +import qualified Data.ByteString.Lazy as LB + +import Hakyll.Core.Resource +import Hakyll.Core.Resource.Provider +import Hakyll.Core.Identifier +import Hakyll.Core.Util.File +import Hakyll.Core.Configuration + +-- | Create a filesystem-based 'ResourceProvider' +-- +fileResourceProvider :: HakyllConfiguration -> IO ResourceProvider +fileResourceProvider configuration = do + -- Retrieve a list of identifiers + list <- map parseIdentifier . filter (not . ignoreFile configuration) <$> + getRecursiveContents False "." + + -- Construct a resource provider + return ResourceProvider + { resourceList = map Resource list + , resourceString = readFile . toFilePath . unResource + , resourceLazyByteString = LB.readFile . toFilePath . unResource + } diff --git a/src/Hakyll/Core/ResourceProvider.hs b/src/Hakyll/Core/ResourceProvider.hs deleted file mode 100644 index dcd4af0..0000000 --- a/src/Hakyll/Core/ResourceProvider.hs +++ /dev/null @@ -1,75 +0,0 @@ --- | This module provides an API for resource providers. Resource providers --- allow Hakyll to get content from resources; the type of resource depends on --- the concrete instance. --- --- A resource is represented by the 'Resource' type. This is basically just a --- newtype wrapper around 'Identifier' -- but it has an important effect: it --- guarantees that a resource with this identifier can be provided by one or --- more resource providers. --- --- Therefore, it is not recommended to read files directly -- you should use the --- provided 'Resource' methods. --- -module Hakyll.Core.ResourceProvider - ( Resource (..) - , ResourceProvider (..) - , resourceExists - , resourceDigest - , resourceModified - ) where - -import Control.Monad ((<=<)) -import Data.Word (Word8) - -import qualified Data.ByteString.Lazy as LB -import OpenSSL.Digest.ByteString.Lazy (digest) -import OpenSSL.Digest (MessageDigest (MD5)) - -import Hakyll.Core.Identifier -import Hakyll.Core.Store - --- | A resource --- --- Invariant: the resource specified by the given identifier must exist --- -newtype Resource = Resource {unResource :: Identifier} - deriving (Eq, Show, Ord) - --- | A value responsible for retrieving and listing resources --- -data ResourceProvider = ResourceProvider - { -- | A list of all resources this provider is able to provide - resourceList :: [Resource] - , -- | Retrieve a certain resource as string - resourceString :: Resource -> IO String - , -- | Retrieve a certain resource as lazy bytestring - resourceLazyByteString :: Resource -> IO LB.ByteString - } - --- | Check if a given identifier has a resource --- -resourceExists :: ResourceProvider -> Identifier -> Bool -resourceExists provider = flip elem $ map unResource $ resourceList provider - --- | Retrieve a digest for a given resource --- -resourceDigest :: ResourceProvider -> Resource -> IO [Word8] -resourceDigest provider = digest MD5 <=< resourceLazyByteString provider - --- | Check if a resource was modified --- -resourceModified :: ResourceProvider -> Resource -> Store -> IO Bool -resourceModified provider resource store = do - -- Get the latest seen digest from the store - lastDigest <- storeGet store itemName $ unResource resource - -- Calculate the digest for the resource - newDigest <- resourceDigest provider resource - -- Check digests - if Just newDigest == lastDigest - -- All is fine, not modified - then return False - -- Resource modified; store new digest - else do storeSet store itemName (unResource resource) newDigest - return True - where - itemName = "Hakyll.Core.ResourceProvider.resourceModified" diff --git a/src/Hakyll/Core/ResourceProvider/FileResourceProvider.hs b/src/Hakyll/Core/ResourceProvider/FileResourceProvider.hs deleted file mode 100644 index 0d89b21..0000000 --- a/src/Hakyll/Core/ResourceProvider/FileResourceProvider.hs +++ /dev/null @@ -1,29 +0,0 @@ --- | A concrete 'ResourceProvider' that gets it's resources from the filesystem --- -module Hakyll.Core.ResourceProvider.FileResourceProvider - ( fileResourceProvider - ) where - -import Control.Applicative ((<$>)) - -import qualified Data.ByteString.Lazy as LB - -import Hakyll.Core.ResourceProvider -import Hakyll.Core.Identifier -import Hakyll.Core.Util.File -import Hakyll.Core.Configuration - --- | Create a filesystem-based 'ResourceProvider' --- -fileResourceProvider :: HakyllConfiguration -> IO ResourceProvider -fileResourceProvider configuration = do - -- Retrieve a list of identifiers - list <- map parseIdentifier . filter (not . ignoreFile configuration) <$> - getRecursiveContents False "." - - -- Construct a resource provider - return ResourceProvider - { resourceList = map Resource list - , resourceString = readFile . toFilePath . unResource - , resourceLazyByteString = LB.readFile . toFilePath . unResource - } diff --git a/src/Hakyll/Core/Rules.hs b/src/Hakyll/Core/Rules.hs index 19df85e..892cf7c 100644 --- a/src/Hakyll/Core/Rules.hs +++ b/src/Hakyll/Core/Rules.hs @@ -37,7 +37,8 @@ import qualified Data.Set as S import Data.Typeable (Typeable) import Data.Binary (Binary) -import Hakyll.Core.ResourceProvider +import Hakyll.Core.Resource +import Hakyll.Core.Resource.Provider import Hakyll.Core.Identifier import Hakyll.Core.Identifier.Pattern import Hakyll.Core.Compiler.Internal diff --git a/src/Hakyll/Core/Rules/Internal.hs b/src/Hakyll/Core/Rules/Internal.hs index 592194d..0e117ec 100644 --- a/src/Hakyll/Core/Rules/Internal.hs +++ b/src/Hakyll/Core/Rules/Internal.hs @@ -18,7 +18,8 @@ import Control.Monad.State (State, evalState) import Data.Monoid (Monoid, mempty, mappend) import Data.Set (Set) -import Hakyll.Core.ResourceProvider +import Hakyll.Core.Resource +import Hakyll.Core.Resource.Provider import Hakyll.Core.Identifier import Hakyll.Core.Identifier.Pattern import Hakyll.Core.Compiler.Internal diff --git a/src/Hakyll/Core/Run.hs b/src/Hakyll/Core/Run.hs index 9a5245d..8e1ba6d 100644 --- a/src/Hakyll/Core/Run.hs +++ b/src/Hakyll/Core/Run.hs @@ -23,8 +23,9 @@ import Hakyll.Core.Identifier import Hakyll.Core.Util.File import Hakyll.Core.Compiler import Hakyll.Core.Compiler.Internal -import Hakyll.Core.ResourceProvider -import Hakyll.Core.ResourceProvider.FileResourceProvider +import Hakyll.Core.Resource +import Hakyll.Core.Resource.Provider +import Hakyll.Core.Resource.Provider.File import Hakyll.Core.Rules.Internal import Hakyll.Core.DirectedGraph import Hakyll.Core.DirectedGraph.DependencySolver diff --git a/src/Hakyll/Core/Writable/CopyFile.hs b/src/Hakyll/Core/Writable/CopyFile.hs index 1cd5fd2..ab9c698 100644 --- a/src/Hakyll/Core/Writable/CopyFile.hs +++ b/src/Hakyll/Core/Writable/CopyFile.hs @@ -12,7 +12,7 @@ import System.Directory (copyFile) import Data.Typeable (Typeable) import Data.Binary (Binary) -import Hakyll.Core.ResourceProvider +import Hakyll.Core.Resource import Hakyll.Core.Writable import Hakyll.Core.Compiler import Hakyll.Core.Identifier diff --git a/src/Hakyll/Web/CompressCss.hs b/src/Hakyll/Web/CompressCss.hs index 2df08fd..090fe10 100644 --- a/src/Hakyll/Web/CompressCss.hs +++ b/src/Hakyll/Web/CompressCss.hs @@ -11,7 +11,7 @@ import Data.List (isPrefixOf) import Control.Arrow ((>>^)) import Hakyll.Core.Compiler -import Hakyll.Core.ResourceProvider +import Hakyll.Core.Resource import Hakyll.Core.Util.String -- | Compiler form of 'compressCss' diff --git a/src/Hakyll/Web/Page.hs b/src/Hakyll/Web/Page.hs index c41647b..5146bdc 100644 --- a/src/Hakyll/Web/Page.hs +++ b/src/Hakyll/Web/Page.hs @@ -67,7 +67,7 @@ import Data.Ord (comparing) import Hakyll.Core.Identifier import Hakyll.Core.Compiler -import Hakyll.Core.ResourceProvider +import Hakyll.Core.Resource import Hakyll.Web.Page.Internal import Hakyll.Web.Page.Read import Hakyll.Web.Page.Metadata diff --git a/src/Hakyll/Web/Template.hs b/src/Hakyll/Web/Template.hs index 9c49278..33e7a9b 100644 --- a/src/Hakyll/Web/Template.hs +++ b/src/Hakyll/Web/Template.hs @@ -59,7 +59,7 @@ import Text.Hamlet (HamletSettings, defaultHamletSettings) import Hakyll.Core.Compiler import Hakyll.Core.Identifier -import Hakyll.Core.ResourceProvider +import Hakyll.Core.Resource import Hakyll.Web.Template.Internal import Hakyll.Web.Template.Read import Hakyll.Web.Page.Internal -- cgit v1.2.3