Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow specifying a metadata provider #780

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions lib/Hakyll/Core/Configuration.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ module Hakyll.Core.Configuration


--------------------------------------------------------------------------------
import Data.Default (Default (..))
import Data.List (isPrefixOf, isSuffixOf)
import System.Directory (canonicalizePath)
import System.Exit (ExitCode)
import System.FilePath (isAbsolute, normalise, takeFileName)
import System.IO.Error (catchIOError)
import System.Process (system)
import Data.Default (Default (..))
import Data.List (isPrefixOf, isSuffixOf)
import System.Directory (canonicalizePath)
import System.Exit (ExitCode)
import System.FilePath (isAbsolute, normalise, takeFileName)
import System.IO.Error (catchIOError)
import System.Process (system)

import Hakyll.Core.Metadata

--------------------------------------------------------------------------------
data Configuration = Configuration
Expand Down Expand Up @@ -78,6 +79,10 @@ data Configuration = Configuration
-- One can also override the port as a command line argument:
-- ./site preview -p 1234
previewPort :: Int
, -- | Function to extract metadata from the files
--
-- By default it returns empty metadata
provideMetadata :: FilePath -> IO Metadata
}

--------------------------------------------------------------------------------
Expand All @@ -98,6 +103,7 @@ defaultConfiguration = Configuration
, inMemoryCache = True
, previewHost = "127.0.0.1"
, previewPort = 8000
, provideMetadata = const (return mempty)
}
where
ignoreFile' path
Expand Down
16 changes: 13 additions & 3 deletions lib/Hakyll/Core/Provider.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module Hakyll.Core.Provider
( -- * Constructing resource providers
Internal.Provider
, newProvider
, newProvider'

-- * Querying resource properties
, Internal.resourceList
Expand All @@ -24,20 +25,29 @@ module Hakyll.Core.Provider


--------------------------------------------------------------------------------
import Hakyll.Core.Metadata
import qualified Hakyll.Core.Provider.Internal as Internal
import qualified Hakyll.Core.Provider.MetadataCache as Internal
import Hakyll.Core.Store (Store)


--------------------------------------------------------------------------------
-- | Create a resource provider
-- | Create a resource provider with the void metadata provider
newProvider :: Store -- ^ Store to use
-> (FilePath -> IO Bool) -- ^ Should we ignore this file?
-> FilePath -- ^ Search directory
-> IO Internal.Provider -- ^ Resulting provider
newProvider store ignore directory = do
newProvider store ignore = newProvider' store ignore (const $ return mempty)

-- | Create a resource provider
newProvider' :: Store -- ^ Store to use
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though it's a bunch of boilerplate, we should probably add a new ProviderOptions together with defaultProviderOptions so we can add new fields in a backwards-compatible way.

-> (FilePath -> IO Bool) -- ^ Should we ignore this file?
-> (FilePath -> IO Metadata) -- ^ Metadata provider
-> FilePath -- ^ Search directory
-> IO Internal.Provider -- ^ Resulting provider
newProvider' store ignore metadata directory = do
-- Delete metadata cache where necessary
p <- Internal.newProvider store ignore directory
p <- Internal.newProvider store ignore metadata directory
mapM_ (Internal.resourceInvalidateMetadataCache p) $
filter (Internal.resourceModified p) $ Internal.resourceList p
return p
10 changes: 7 additions & 3 deletions lib/Hakyll/Core/Provider/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import System.Time (formatCalendarTime, toCalendarTime)

--------------------------------------------------------------------------------
import Hakyll.Core.Identifier
import Hakyll.Core.Metadata
import Hakyll.Core.Store (Store)
import qualified Hakyll.Core.Store as Store
import Hakyll.Core.Util.File
Expand Down Expand Up @@ -95,16 +96,19 @@ data Provider = Provider
providerOldFiles :: Map Identifier ResourceInfo
, -- | Underlying persistent store for caching
providerStore :: Store
} deriving (Show)
-- | A custom function to extract metadata from files
, providerMetadata :: FilePath -> IO Metadata
}


--------------------------------------------------------------------------------
-- | Create a resource provider
newProvider :: Store -- ^ Store to use
-> (FilePath -> IO Bool) -- ^ Should we ignore this file?
-> (FilePath -> IO Metadata) -- ^ Metadata provider
-> FilePath -- ^ Search directory
-> IO Provider -- ^ Resulting provider
newProvider store ignore directory = do
newProvider store ignore metadata directory = do
list <- map fromFilePath <$> getRecursiveContents ignore directory
let universe = S.fromList list
files <- fmap (maxmtime . M.fromList) $ forM list $ \identifier -> do
Expand All @@ -116,7 +120,7 @@ newProvider store ignore directory = do
oldFiles <- fromMaybe mempty . Store.toMaybe <$> Store.get store oldKey
oldFiles `deepseq` Store.set store oldKey files

return $ Provider directory files oldFiles store
return $ Provider directory files oldFiles store metadata
where
oldKey = ["Hakyll.Core.Provider.Internal.newProvider", "oldFiles"]

Expand Down
5 changes: 3 additions & 2 deletions lib/Hakyll/Core/Provider/Metadata.hs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import Hakyll.Core.Identifier
import Hakyll.Core.Metadata
import Hakyll.Core.Provider.Internal
import System.IO as IO
import System.IO.Error (modifyIOError, ioeSetLocation)
import System.IO.Error (ioeSetLocation, modifyIOError)


--------------------------------------------------------------------------------
Expand All @@ -42,7 +42,8 @@ loadMetadata p identifier = do
Nothing -> return mempty
Just mi' -> loadMetadataFile $ resourceFilePath p mi'

return (md <> emd, body)
mdp <- providerMetadata p fp
return (md <> emd <> mdp, body)
where
normal = setVersion Nothing identifier
fp = resourceFilePath p identifier
Expand Down
4 changes: 2 additions & 2 deletions lib/Hakyll/Core/Runtime.hs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ run config logger rules = do
Logger.message logger "Creating store..."
store <- Store.new (inMemoryCache config) $ storeDirectory config
Logger.message logger "Creating provider..."
provider <- newProvider store (shouldIgnoreFile config) $
providerDirectory config
provider <- newProvider' store (shouldIgnoreFile config) (provideMetadata config)
(providerDirectory config)
Logger.message logger "Running rules..."
ruleSet <- runRules rules provider

Expand Down