on master help sign in
Fix inotify preview polling
commit4c75843c81d83980ff5757520b2e3e93ad9084ca authorJasper Van der Jeugt <jaspervdj@gmail.com> dateFri 18 Feb 2011, 18:15 (16 years ago) parent7aac6cc
3 files changed+35−47
src/Hakyll.hs−2 src/Hakyll/Main.hs+5−7 src/Hakyll/Web/Preview/INotify.hs+30−38
src/Hakyll.hs−2
@@ -12,7 +12,6 @@ module Hakyll
1212 , module Hakyll.Core.Util.File
1313 , module Hakyll.Core.Writable
1414 , module Hakyll.Main
15− , module Hakyll.Web
1615 , module Hakyll.Web.CompressCss
1716 , module Hakyll.Web.Feed
1817 , module Hakyll.Web.FileType
@@ -37,7 +36,6 @@ import Hakyll.Core.Util.Arrow
3736import Hakyll.Core.Util.File
3837import Hakyll.Core.Writable
3938import Hakyll.Main
40−import Hakyll.Web
4139import Hakyll.Web.CompressCss
4240import Hakyll.Web.Feed
4341import Hakyll.Web.FileType
src/Hakyll/Main.hs+5−7
@@ -6,10 +6,9 @@ module Hakyll.Main
66 ) where
77
88import Control.Concurrent (forkIO)
9−import Control.Monad (when, forM_)
9+import Control.Monad (when)
1010import System.Environment (getProgName, getArgs)
1111import System.Directory (doesDirectoryExist, removeDirectoryRecursive)
12−import qualified Data.Set as S
1312
1413import Hakyll.Core.Configuration
1514import Hakyll.Core.Run
@@ -87,16 +86,15 @@ preview configuration rules port = do
8786 -- Build once, keep the rule set
8887 ruleSet <- run configuration rules
8988
90− -- Debug: show the resources used
91− forM_ (S.toList $ rulesResources ruleSet) $ putStrLn . show
89+ -- Get the resource list and a callback for the preview poll
90+ let resources = rulesResources ruleSet
91+ callback = build configuration rules
9292
93− {-
9493 -- Fork a thread polling for changes
95− _ <- forkIO $ previewPoll configuration "." $ build configuration rules
94+ _ <- forkIO $ previewPoll configuration resources callback
9695
9796 -- Run the server in the main thread
9897 server configuration port
99− -}
10098
10199-- | Rebuild the site
102100--
src/Hakyll/Web/Preview/INotify.hs+30−38
@@ -4,57 +4,49 @@ module Hakyll.Web.Preview.INotify
44 ( previewPoll
55 ) where
66
7−import Control.Monad (forM_, when, unless)
8−import System.Directory (doesDirectoryExist)
9−import System.FilePath ((</>))
10−import Data.List (isPrefixOf)
7+import Control.Monad (forM_, when)
8+import Data.Set (Set)
9+import qualified Data.Set as S
10+import System.FilePath (takeDirectory)
1111
1212import System.INotify
1313
14−import Hakyll.Core.Util.File
1514import Hakyll.Core.Configuration
15+import Hakyll.Core.ResourceProvider
16+import Hakyll.Core.Identifier
1617
1718-- | Calls the given callback when the directory tree changes
1819--
1920previewPoll :: HakyllConfiguration -- ^ Configuration
20− -> FilePath -- ^ Root directory
21+ -> Set Resource -- ^ Resources to watch
2122 -> IO () -- ^ Action called when something changes
2223 -> IO () -- ^ Can block forever
23−previewPoll conf directory callback = do
24+previewPoll _ resources callback = do
2425 -- Initialize inotify
2526 inotify <- initINotify
2627
27− -- Start by watching all directories
28− contents <- getRecursiveContents True directory
29− forM_ contents $ \file -> do
30− isDir <- doesDirectoryExist file
31− when isDir $ watchDirectory conf inotify file callback
28+ let -- A set of file paths
29+ paths = S.map (toFilePath . unResource) resources
3230
33−-- | Start watching a directory recursively: when another directory is created
34−-- inside this directory, start watching that one as well...
35−--
36−watchDirectory :: HakyllConfiguration -- ^ Configuration
37− -> INotify -- ^ INotify handle
38− -> FilePath -- ^ Directory to watch
39− -> IO () -- ^ Callback
40− -> IO () -- ^ No result
41−watchDirectory conf inotify path callback =
42− unless (isFileInternal conf path) $ do
43− _ <- addWatch inotify interesting path $ \event -> do
44− putStrLn $ "Triggered: " ++ show event
45− callback' inotify path event
31+ -- A list of directories
32+ directories = S.toList $ S.map (notEmpty . takeDirectory) paths
33+
34+ -- Make sure a directory name is not empty
35+ notEmpty "" = "."
36+ notEmpty x = x
37+
38+ -- Execute the callback when path is known
39+ ifResource path = when (path `S.member` paths) $ do
40+ putStrLn $ "Changed: " ++ path
41+ callback
42+
43+ -- Add a watcher for every directory
44+ forM_ directories $ \directory -> do
45+ putStrLn $ "Adding watch for " ++ directory
46+ _ <- addWatch inotify interesting directory $ \e -> case e of
47+ (Modified _ (Just p)) -> ifResource p
48+ _ -> return ()
4649 return ()
4750 where
48− callback' i p (Created True n) = watchDirectory conf i (p </> n) callback
49− callback' _ _ (Created _ p) = whenProper $ Just p
50− callback' _ _ (Modified _ p) = whenProper p
51− callback' _ _ (MovedOut _ p _) = whenProper $ Just p
52− callback' _ _ (MovedIn _ p _) = whenProper $ Just p
53− callback' _ _ (Deleted _ p) = whenProper $ Just p
54− callback' _ _ _ = return ()
55−
56− interesting = [Modify, Create, Move, Delete]
57−
58− -- Call the callback only for proper files
59− whenProper Nothing = return ()
60− whenProper (Just f) = unless ("." `isPrefixOf` f) callback
51+ -- Interesting events
52+ interesting = [Modify]