@@ -1,40 +1,64 @@
1+--------------------------------------------------------------------------------
1module Hakyll.Preview.Poll
2module Hakyll.Preview.Poll
2 ( watchUpdates
3 ( watchUpdates
5--------------------------------------------------------------------------------
7--------------------------------------------------------------------------------
8+import Control.Concurrent.MVar (newMVar, putMVar, takeMVar)
9+import Control.Monad (when)
6−import Filesystem.Path.CurrentOS (decodeString, encodeString)
10+import Filesystem.Path.CurrentOS (decodeString, encodeString)
7−import System.FSNotify (startManagerConf, watchTree,
11+import System.Directory (canonicalizePath)
12+import System.FilePath (pathSeparators)
8− Event(..), WatchConfig(..))
13+import System.FSNotify (Event (..), WatchConfig (..),
14+ startManagerConf, watchTree)
10--------------------------------------------------------------------------------
17--------------------------------------------------------------------------------
11import Hakyll.Core.Configuration
18import Hakyll.Core.Configuration
12−
19+import Hakyll.Core.Identifier
20+import Hakyll.Core.Identifier.Pattern
15--------------------------------------------------------------------------------
23--------------------------------------------------------------------------------
16-- | A thread that watches for updates in a 'providerDirectory' and recompiles
24-- | A thread that watches for updates in a 'providerDirectory' and recompiles
17-- a site as soon as any changes occur
25-- a site as soon as any changes occur
18−watchUpdates :: Configuration -> IO () -> IO ()
26+watchUpdates :: Configuration -> IO Pattern -> IO ()
19watchUpdates conf update = do
27watchUpdates conf update = do
28+ let providerDir = decodeString $ providerDirectory conf
20− _ <- update
30+ pattern <- update
31+ fullProviderDir <- canonicalizePath $ providerDirectory conf
21− manager <- startManagerConf (Debounce 0.1)
32+ manager <- startManagerConf (Debounce 0.1)
22− watchTree manager path (not . isRemove) update'
24− path = decodeString $ providerDirectory conf
26− ignore <- shouldIgnoreFile conf $ eventPath evt
27− if ignore then return () else update
34+ let allowed event = do
35+ -- Absolute path of the changed file. This must be inside provider
36+ -- dir, since that's the only dir we're watching.
37+ let path = eventPath event
38+ relative = dropWhile (`elem` pathSeparators) $
39+ drop (length fullProviderDir) path
40+ identifier = fromFilePath relative
42+ shouldIgnore <- shouldIgnoreFile conf path
43+ return $ not shouldIgnore && matches pattern identifier
45+ watchTree manager providerDir (not . isRemove) $ \event -> do
47+ allowed' <- allowed event
48+ when allowed' $ update >> return ()
52+--------------------------------------------------------------------------------
30eventPath :: Event -> FilePath
53eventPath :: Event -> FilePath
31eventPath evt = encodeString $ evtPath evt
54eventPath evt = encodeString $ evtPath evt
33− evtPath (Added p _) = p
56+ evtPath (Added p _) = p
34 evtPath (Modified p _) = p
57 evtPath (Modified p _) = p
35− evtPath (Removed p _) = p
58+ evtPath (Removed p _) = p
61+--------------------------------------------------------------------------------
38isRemove :: Event -> Bool
62isRemove :: Event -> Bool
39isRemove (Removed _ _) = True
63isRemove (Removed _ _) = True
40−isRemove _ = False
64+isRemove _ = False