Add snapshots

This commit is contained in:
Jasper Van der Jeugt 2012-11-24 10:56:19 +01:00
parent bc192a127b
commit 0a6b2b2598
6 changed files with 138 additions and 60 deletions

View file

@ -10,9 +10,16 @@ module Hakyll.Core.Compiler
, getResourceString , getResourceString
, getResourceLBS , getResourceLBS
, getResourceWith , getResourceWith
, require
, requireBody , Internal.Snapshot
, requireAll , saveSnapshot
, Internal.require
, Internal.requireSnapshot
, Internal.requireBody
, Internal.requireSnapshotBody
, Internal.requireAll
, Internal.requireAllSnapshots
, cached , cached
, unsafeCompiler , unsafeCompiler
, debugCompiler , debugCompiler
@ -30,7 +37,7 @@ import System.Environment (getProgName)
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
import Hakyll.Core.Compiler.Internal import Hakyll.Core.Compiler.Internal
import Hakyll.Core.Compiler.Require import qualified Hakyll.Core.Compiler.Require as Internal
import Hakyll.Core.Identifier import Hakyll.Core.Identifier
import Hakyll.Core.Item import Hakyll.Core.Item
import Hakyll.Core.Logger as Logger import Hakyll.Core.Logger as Logger
@ -93,6 +100,14 @@ getResourceWith reader = do
show fp ++ " not found" show fp ++ " not found"
--------------------------------------------------------------------------------
saveSnapshot :: (Binary a, Typeable a)
=> Internal.Snapshot -> Item a -> Compiler ()
saveSnapshot snapshot item = do
store <- compilerStore <$> compilerAsk
compilerUnsafeIO $ Internal.saveSnapshot store snapshot item
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
cached :: (Binary a, Typeable a) cached :: (Binary a, Typeable a)
=> String => String

View file

@ -1,9 +1,14 @@
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
module Hakyll.Core.Compiler.Require module Hakyll.Core.Compiler.Require
( save ( Snapshot
, save
, saveSnapshot
, require , require
, requireSnapshot
, requireBody , requireBody
, requireSnapshotBody
, requireAll , requireAll
, requireAllSnapshots
) where ) where
@ -25,45 +30,82 @@ import qualified Hakyll.Core.Store as Store
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
save :: (Binary a, Typeable a) => Store -> Identifier -> a -> IO () type Snapshot = String
save store identifier x = Store.set store (key identifier) x
--------------------------------------------------------------------------------
save :: (Binary a, Typeable a) => Store -> Item a -> IO ()
save store item = saveSnapshot store final item
--------------------------------------------------------------------------------
saveSnapshot :: (Binary a, Typeable a)
=> Store -> Snapshot -> Item a -> IO ()
saveSnapshot store snapshot item =
Store.set store (key (itemIdentifier item) snapshot) (itemBody item)
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
require :: (Binary a, Typeable a) => Identifier -> Compiler (Item a) require :: (Binary a, Typeable a) => Identifier -> Compiler (Item a)
require id' = do require id' = requireSnapshot id' final
--------------------------------------------------------------------------------
requireSnapshot :: (Binary a, Typeable a)
=> Identifier -> Snapshot -> Compiler (Item a)
requireSnapshot id' snapshot = do
store <- compilerStore <$> compilerAsk store <- compilerStore <$> compilerAsk
compilerTellDependencies [IdentifierDependency id'] compilerTellDependencies [IdentifierDependency id']
compilerResult $ CompilerRequire id' $ do compilerResult $ CompilerRequire id' $ do
result <- compilerUnsafeIO $ Store.get store (key id') result <- compilerUnsafeIO $ Store.get store (key id' snapshot)
case result of case result of
Store.NotFound -> compilerThrow notFound Store.NotFound -> compilerThrow notFound
Store.WrongType e r -> compilerThrow $ wrongType e r Store.WrongType e r -> compilerThrow $ wrongType e r
Store.Found x -> return $ Item id' x Store.Found x -> return $ Item id' x
where where
notFound = notFound =
"Hakyll.Core.Compiler.Require.require: " ++ show id' ++ " was " ++ "Hakyll.Core.Compiler.Require.require: " ++ show id' ++
"not found in the cache, the cache might be corrupted or " ++ " (snapshot " ++ snapshot ++ ") was not found in the cache, " ++
"the cache might be corrupted or " ++
"the item you are referring to might not exist" "the item you are referring to might not exist"
wrongType e r = wrongType e r =
"Hakyll.Core.Compiler.Require.require: " ++ show id' ++ " was found " ++ "Hakyll.Core.Compiler.Require.require: " ++ show id' ++
"in the cache, but does not have the right type: expected " ++ show e ++ " (snapshot " ++ snapshot ++ ") was found in the cache, " ++
"but does not have the right type: expected " ++ show e ++
" but got " ++ show r " but got " ++ show r
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
requireBody :: (Binary a, Typeable a) => Identifier -> Compiler a requireBody :: (Binary a, Typeable a) => Identifier -> Compiler a
requireBody = fmap itemBody . require requireBody id' = requireSnapshotBody id' final
--------------------------------------------------------------------------------
requireSnapshotBody :: (Binary a, Typeable a)
=> Identifier -> Snapshot -> Compiler a
requireSnapshotBody id' snapshot = fmap itemBody $ requireSnapshot id' snapshot
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
requireAll :: (Binary a, Typeable a) => Pattern -> Compiler [Item a] requireAll :: (Binary a, Typeable a) => Pattern -> Compiler [Item a]
requireAll pattern = do requireAll pattern = requireAllSnapshots pattern final
matching <- getMatches pattern
mapM require matching
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
key :: Identifier -> [String] requireAllSnapshots :: (Binary a, Typeable a)
key identifier = ["Hakyll.Core.Compiler.Require", show identifier] => Pattern -> Snapshot -> Compiler [Item a]
requireAllSnapshots pattern snapshot = do
matching <- getMatches pattern
mapM (\i -> requireSnapshot i snapshot) matching
--------------------------------------------------------------------------------
key :: Identifier -> String -> [String]
key identifier snapshot =
["Hakyll.Core.Compiler.Require", show identifier, snapshot]
--------------------------------------------------------------------------------
final :: Snapshot
final = "final"

View file

@ -27,7 +27,6 @@ import Hakyll.Core.Compiler.Require
import Hakyll.Core.Configuration import Hakyll.Core.Configuration
import Hakyll.Core.Dependencies import Hakyll.Core.Dependencies
import Hakyll.Core.Identifier import Hakyll.Core.Identifier
import Hakyll.Core.Item
import Hakyll.Core.Item.SomeItem import Hakyll.Core.Item.SomeItem
import Hakyll.Core.Logger (Logger) import Hakyll.Core.Logger (Logger)
import qualified Hakyll.Core.Logger as Logger import qualified Hakyll.Core.Logger as Logger
@ -194,8 +193,7 @@ chase trail id'
-- Huge success -- Huge success
CompilerDone (SomeItem item) cwrite -> do CompilerDone (SomeItem item) cwrite -> do
-- TODO: Sanity check on itemIdentifier? -- TODO: Sanity check on itemIdentifier?
let body = itemBody item let facts = compilerDependencies cwrite
facts = compilerDependencies cwrite
cacheHits cacheHits
| compilerCacheHits cwrite <= 0 = "updated" | compilerCacheHits cwrite <= 0 = "updated"
| otherwise = "cached " | otherwise = "cached "
@ -213,7 +211,7 @@ chase trail id'
Logger.debug logger $ "Routed to " ++ path Logger.debug logger $ "Routed to " ++ path
-- Save! (For require) -- Save! (For require)
liftIO $ save store id' body liftIO $ save store item
-- Update state -- Update state
modify $ \s -> s modify $ \s -> s

View file

@ -1,39 +1,47 @@
--------------------------------------------------------------------------------
-- | Module providing the main hakyll function and command-line argument parsing -- | Module providing the main hakyll function and command-line argument parsing
--
{-# LANGUAGE CPP #-} {-# LANGUAGE CPP #-}
module Hakyll.Main module Hakyll.Main
( hakyll ( hakyll
, hakyllWith , hakyllWith
) where ) where
import Control.Monad (when)
import System.Directory (doesDirectoryExist, removeDirectoryRecursive)
import System.Environment (getProgName, getArgs)
import System.Process (system)
import Hakyll.Core.Configuration --------------------------------------------------------------------------------
import Hakyll.Core.Identifier import Control.Monad (when)
import Hakyll.Core.Runtime import System.Directory (doesDirectoryExist,
import Hakyll.Core.Rules removeDirectoryRecursive)
import System.Environment (getArgs, getProgName)
import System.Process (system)
--------------------------------------------------------------------------------
import Hakyll.Core.Configuration
import Hakyll.Core.Rules
import Hakyll.Core.Runtime
--------------------------------------------------------------------------------
#ifdef PREVIEW_SERVER #ifdef PREVIEW_SERVER
import Control.Applicative ((<$>)) import Control.Applicative ((<$>))
import Control.Concurrent (forkIO) import Control.Concurrent (forkIO)
import qualified Data.Set as S import qualified Data.Set as S
import Hakyll.Core.Identifier
import Hakyll.Core.Rules.Internal import Hakyll.Core.Rules.Internal
import Hakyll.Web.Preview.Poll import Hakyll.Web.Preview.Poll
import Hakyll.Web.Preview.Server import Hakyll.Web.Preview.Server
#endif #endif
--------------------------------------------------------------------------------
-- | This usualy is the function with which the user runs the hakyll compiler -- | This usualy is the function with which the user runs the hakyll compiler
--
hakyll :: Rules a -> IO () hakyll :: Rules a -> IO ()
hakyll = hakyllWith defaultConfiguration hakyll = hakyllWith defaultConfiguration
--------------------------------------------------------------------------------
-- | A variant of 'hakyll' which allows the user to specify a custom -- | A variant of 'hakyll' which allows the user to specify a custom
-- configuration -- configuration
--
hakyllWith :: Configuration -> Rules a -> IO () hakyllWith :: Configuration -> Rules a -> IO ()
hakyllWith conf rules = do hakyllWith conf rules = do
args <- getArgs args <- getArgs
@ -49,15 +57,17 @@ hakyllWith conf rules = do
["deploy"] -> deploy conf ["deploy"] -> deploy conf
_ -> help _ -> help
--------------------------------------------------------------------------------
-- | Build the site -- | Build the site
--
build :: Configuration -> Rules a -> IO () build :: Configuration -> Rules a -> IO ()
build conf rules = do build conf rules = do
_ <- run conf rules _ <- run conf rules
return () return ()
--------------------------------------------------------------------------------
-- | Remove the output directories -- | Remove the output directories
--
clean :: Configuration -> IO () clean :: Configuration -> IO ()
clean conf = do clean conf = do
remove $ destinationDirectory conf remove $ destinationDirectory conf
@ -68,8 +78,9 @@ clean conf = do
exists <- doesDirectoryExist dir exists <- doesDirectoryExist dir
when exists $ removeDirectoryRecursive dir when exists $ removeDirectoryRecursive dir
--------------------------------------------------------------------------------
-- | Show usage information. -- | Show usage information.
--
help :: IO () help :: IO ()
help = do help = do
name <- getProgName name <- getProgName
@ -95,8 +106,9 @@ help = do
previewServerDisabled previewServerDisabled
#endif #endif
--------------------------------------------------------------------------------
-- | Preview the site -- | Preview the site
--
preview :: Configuration -> Rules a -> Int -> IO () preview :: Configuration -> Rules a -> Int -> IO ()
#ifdef PREVIEW_SERVER #ifdef PREVIEW_SERVER
preview conf rules port = do preview conf rules port = do
@ -111,15 +123,17 @@ preview conf rules port = do
preview _ _ _ = previewServerDisabled preview _ _ _ = previewServerDisabled
#endif #endif
--------------------------------------------------------------------------------
-- | Rebuild the site -- | Rebuild the site
--
rebuild :: Configuration -> Rules a -> IO () rebuild :: Configuration -> Rules a -> IO ()
rebuild conf rules = do rebuild conf rules = do
clean conf clean conf
build conf rules build conf rules
--------------------------------------------------------------------------------
-- | Start a server -- | Start a server
--
server :: Configuration -> Int -> IO () server :: Configuration -> Int -> IO ()
#ifdef PREVIEW_SERVER #ifdef PREVIEW_SERVER
server conf port = do server conf port = do
@ -131,15 +145,17 @@ server conf port = do
server _ _ = previewServerDisabled server _ _ = previewServerDisabled
#endif #endif
--------------------------------------------------------------------------------
-- | Upload the site -- | Upload the site
--
deploy :: Configuration -> IO () deploy :: Configuration -> IO ()
deploy conf = do deploy conf = do
_ <- system $ deployCommand conf _ <- system $ deployCommand conf
return () return ()
--------------------------------------------------------------------------------
-- | Print a warning message about the preview serving not being enabled -- | Print a warning message about the preview serving not being enabled
--
#ifndef PREVIEW_SERVER #ifndef PREVIEW_SERVER
previewServerDisabled :: IO () previewServerDisabled :: IO ()
previewServerDisabled = previewServerDisabled =

View file

@ -6,17 +6,14 @@ module Hakyll.Core.Runtime.Tests
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
import System.FilePath ((</>)) import System.FilePath ((</>))
import Test.Framework (Test, testGroup) import Test.Framework (Test, testGroup)
import Test.HUnit (Assertion, (@?=)) import Test.HUnit (Assertion, (@?=))
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
import Hakyll.Core.Configuration import Hakyll
import Hakyll.Core.Routes
import Hakyll.Core.Rules
import Hakyll.Core.Runtime import Hakyll.Core.Runtime
import Hakyll.Web.Page
import TestSuite.Util import TestSuite.Util
@ -31,7 +28,18 @@ case01 = withTestConfiguration $ \config -> do
_ <- run config $ do _ <- run config $ do
match "*.md" $ do match "*.md" $ do
route $ setExtension "html" route $ setExtension "html"
compile $ pageCompiler compile $ do
body <- getResourceBody
saveSnapshot "raw" body
return $ renderPandoc body
out <- readFile $ destinationDirectory config </> "example.html" match "bodies.txt" $ route idRoute
lines out @?= ["<p>This is an example.</p>"] create "bodies.txt" $ do
items <- requireAllSnapshots "*.md" "raw" :: Compiler [Item String]
makeItem $ concat $ map itemBody items
example <- readFile $ destinationDirectory config </> "example.html"
lines example @?= ["<p>This is an example.</p>"]
bodies <- readFile $ destinationDirectory config </> "bodies.txt"
head (lines bodies) @?= "This is an example."

View file

@ -61,7 +61,6 @@ wrongType = withTestStore $ \store -> do
-- Store a string and try to fetch an int -- Store a string and try to fetch an int
Store.set store ["foo", "bar"] ("qux" :: String) Store.set store ["foo", "bar"] ("qux" :: String)
value <- Store.get store ["foo", "bar"] :: IO (Store.Result Int) value <- Store.get store ["foo", "bar"] :: IO (Store.Result Int)
print value
H.assert $ case value of H.assert $ case value of
Store.WrongType e t -> Store.WrongType e t ->
e == typeOf (undefined :: Int) && e == typeOf (undefined :: Int) &&