on master help sign in
Added autocompile mode to replace preview mode.
6611e86Jasper Van der Jeugt
hakyll.cabal+1
@@ -33,6 +33,7 @@ library
33 network >= 2,
33 network >= 2,
34 mtl >= 1.1,
34 mtl >= 1.1,
35 old-locale >= 1,
35 old-locale >= 1,
36+ old-time >= 1,
36 time >= 1,
37 time >= 1,
37 binary >= 0.5,
38 binary >= 0.5,
38 QuickCheck >= 2
39 QuickCheck >= 2
src/Text/Hakyll.hs+25−4
@@ -13,14 +13,17 @@ module Text.Hakyll
13 , hakyllWithConfiguration
13 , hakyllWithConfiguration
14 ) where
14 ) where
15
15
16−import Control.Monad.Reader (runReaderT, liftIO)
16+import Control.Monad.Reader (runReaderT, liftIO, ask)
17+import Control.Concurrent (forkIO, threadDelay)
17import Control.Monad (when)
18import Control.Monad (when)
18import qualified Data.Map as M
19import qualified Data.Map as M
19import System.Environment (getArgs, getProgName)
20import System.Environment (getArgs, getProgName)
20import System.Directory (doesDirectoryExist, removeDirectoryRecursive)
21import System.Directory (doesDirectoryExist, removeDirectoryRecursive)
22+import System.Time (getClockTime)
21
23
22import Network.Hakyll.SimpleServer (simpleServer)
24import Network.Hakyll.SimpleServer (simpleServer)
23import Text.Hakyll.Hakyll
25import Text.Hakyll.Hakyll
26+import Text.Hakyll.File
24
27
25-- | The default hakyll configuration.
28-- | The default hakyll configuration.
26defaultHakyllConfiguration :: HakyllConfiguration
29defaultHakyllConfiguration :: HakyllConfiguration
@@ -29,6 +32,7 @@ defaultHakyllConfiguration = HakyllConfiguration
29 , siteDirectory = "_site"
32 , siteDirectory = "_site"
30 , cacheDirectory = "_cache"
33 , cacheDirectory = "_cache"
31 , enableIndexUrl = False
34 , enableIndexUrl = False
35+ , previewPollDelay = 1000000
32 }
36 }
33
37
34-- | Main function to run Hakyll with the default configuration.
38-- | Main function to run Hakyll with the default configuration.
@@ -41,8 +45,8 @@ hakyllWithConfiguration configuration buildFunction = do
41 args <- getArgs
45 args <- getArgs
42 let f = case args of ["build"] -> buildFunction
46 let f = case args of ["build"] -> buildFunction
43 ["clean"] -> clean
47 ["clean"] -> clean
44− ["preview", p] -> buildFunction >> server (read p)
48+ ["preview", p] -> preview buildFunction (read p)
45− ["preview"] -> buildFunction >> server 8000
49+ ["preview"] -> preview buildFunction 8000
46 ["server", p] -> server (read p)
50 ["server", p] -> server (read p)
47 ["server"] -> server 8000
51 ["server"] -> server 8000
48 _ -> help
52 _ -> help
@@ -57,6 +61,23 @@ clean = do askHakyll siteDirectory >>= remove'
57 exists <- doesDirectoryExist dir
61 exists <- doesDirectoryExist dir
58 when exists $ removeDirectoryRecursive dir
62 when exists $ removeDirectoryRecursive dir
59
63
64+-- | Autocompile mode.
65+preview :: Hakyll () -> Integer -> Hakyll ()
66+preview buildFunction port = do
67+ buildFunction
68+ _ <- startServer
69+ liftIO getClockTime >>= run
70+ where
71+ startServer = do configuration <- ask
72+ liftIO $ forkIO $ runReaderT (server port) configuration
73+ run time = do delay <- askHakyll previewPollDelay
74+ liftIO $ threadDelay delay
75+ contents <- getRecursiveContents "."
76+ valid <- isMoreRecent time contents
77+ if valid then run time
78+ else do buildFunction
79+ liftIO getClockTime >>= run
80+
60-- | Show usage information.
81-- | Show usage information.
61help :: Hakyll ()
82help :: Hakyll ()
62help = liftIO $ do
83help = liftIO $ do
@@ -68,7 +89,7 @@ help = liftIO $ do
68 ++ name ++ " build Generate the site.\n"
89 ++ name ++ " build Generate the site.\n"
69 ++ name ++ " clean Clean up and remove cache.\n"
90 ++ name ++ " clean Clean up and remove cache.\n"
70 ++ name ++ " help Show this message.\n"
91 ++ name ++ " help Show this message.\n"
71− ++ name ++ " preview [port] Generate site, then start a server.\n"
92+ ++ name ++ " preview [port] Run a server and autocompile.\n"
72 ++ name ++ " server [port] Run a local test server.\n"
93 ++ name ++ " server [port] Run a local test server.\n"
73
94
74-- | Start a server at the given port number.
95-- | Start a server at the given port number.
src/Text/Hakyll/File.hs+17−7
@@ -10,12 +10,14 @@ module Text.Hakyll.File
10 , getRecursiveContents
10 , getRecursiveContents
11 , sortByBaseName
11 , sortByBaseName
12 , havingExtension
12 , havingExtension
13− , isMoreRecent
14 , directory
13 , directory
14+ , isMoreRecent
15+ , isFileMoreRecent
15 ) where
16 ) where
16
17
17import System.Directory
18import System.Directory
18import System.FilePath
19import System.FilePath
20+import System.Time (ClockTime)
19import Control.Monad
21import Control.Monad
20import Data.List (isPrefixOf, sortBy)
22import Data.List (isPrefixOf, sortBy)
21import Control.Monad.Reader (liftIO)
23import Control.Monad.Reader (liftIO)
@@ -144,14 +146,22 @@ havingExtension extension = filter ((==) extension . takeExtension)
144directory :: (FilePath -> Hakyll ()) -> FilePath -> Hakyll ()
146directory :: (FilePath -> Hakyll ()) -> FilePath -> Hakyll ()
145directory action dir = getRecursiveContents dir >>= mapM_ action
147directory action dir = getRecursiveContents dir >>= mapM_ action
146
148
147−-- | Check if a file is newer then a number of given files.
149+-- | Check if a timestamp is newer then a number of given files.
148−isMoreRecent :: FilePath -- ^ The cached file.
150+isMoreRecent :: ClockTime -- ^ The time to check.
149 -> [FilePath] -- ^ Dependencies of the cached file.
151 -> [FilePath] -- ^ Dependencies of the cached file.
150 -> Hakyll Bool
152 -> Hakyll Bool
151−isMoreRecent file depends = do
153+isMoreRecent _ [] = return True
154+isMoreRecent timeStamp depends = do
155+ dependsModified <- liftIO $ mapM getModificationTime depends
156+ return (timeStamp >= maximum dependsModified)
157+
158+-- | Check if a file is newer then a number of given files.
159+isFileMoreRecent :: FilePath -- ^ The cached file.
160+ -> [FilePath] -- ^ Dependencies of the cached file.
161+ -> Hakyll Bool
162+isFileMoreRecent file depends = do
152 exists <- liftIO $ doesFileExist file
163 exists <- liftIO $ doesFileExist file
153 if not exists
164 if not exists
154 then return False
165 then return False
155− else do dependsModified <- liftIO $ mapM getModificationTime depends
156− fileModified <- liftIO $ getModificationTime file
166+ else do timeStamp <- liftIO $ getModificationTime file
157− return (fileModified >= maximum dependsModified)
167+ isMoreRecent timeStamp depends
src/Text/Hakyll/Hakyll.hs+2
@@ -21,6 +21,8 @@ data HakyllConfiguration = HakyllConfiguration
21 cacheDirectory :: FilePath
21 cacheDirectory :: FilePath
22 , -- | Enable index links.
22 , -- | Enable index links.
23 enableIndexUrl :: Bool
23 enableIndexUrl :: Bool
24+ , -- | Delay between polls in preview mode.
25+ previewPollDelay :: Int
24 }
26 }
25
27
26-- | Our custom monad stack.
28-- | Our custom monad stack.
src/Text/Hakyll/Internal/Cache.hs+1−1
@@ -27,4 +27,4 @@ getFromCache = liftIO . decodeFile <=< toCache
27
27
28-- | Check if a file in the cache is more recent than a number of other files.
28-- | Check if a file in the cache is more recent than a number of other files.
29isCacheMoreRecent :: FilePath -> [FilePath] -> Hakyll Bool
29isCacheMoreRecent :: FilePath -> [FilePath] -> Hakyll Bool
30−isCacheMoreRecent file depends = toCache file >>= flip isMoreRecent depends
30+isCacheMoreRecent file depends = toCache file >>= flip isFileMoreRecent depends
src/Text/Hakyll/Render.hs+1−1
@@ -32,7 +32,7 @@ depends :: FilePath -- ^ File to be rendered or created.
32 -> Hakyll ()
32 -> Hakyll ()
33depends file dependencies action = do
33depends file dependencies action = do
34 destination <- toDestination file
34 destination <- toDestination file
35− valid <- isMoreRecent destination dependencies
35+ valid <- isFileMoreRecent destination dependencies
36 unless valid action
36 unless valid action
37
37
38-- | Render to a Page.
38-- | Render to a Page.