on master help sign in
Merge github.com:jaspervdj/hakyll into fsnotify
b5e34c6Simonas Kazlauskas
hakyll.cabal+2−2
@@ -139,7 +139,7 @@ Library
139 binary >= 0.5 && < 0.8,
139 binary >= 0.5 && < 0.8,
140 blaze-html >= 0.5 && < 0.7,
140 blaze-html >= 0.5 && < 0.7,
141 blaze-markup >= 0.5.1 && < 0.6,
141 blaze-markup >= 0.5.1 && < 0.6,
142− bytestring >= 0.10 && < 0.11,
142+ bytestring >= 0.9 && < 0.11,
143 citeproc-hs >= 0.3.2 && < 0.4,
143 citeproc-hs >= 0.3.2 && < 0.4,
144 containers >= 0.3 && < 0.6,
144 containers >= 0.3 && < 0.6,
145 cryptohash >= 0.7 && < 0.9,
145 cryptohash >= 0.7 && < 0.9,
@@ -215,7 +215,7 @@ Test-suite hakyll-tests
215 binary >= 0.5 && < 0.8,
215 binary >= 0.5 && < 0.8,
216 blaze-html >= 0.5 && < 0.7,
216 blaze-html >= 0.5 && < 0.7,
217 blaze-markup >= 0.5.1 && < 0.6,
217 blaze-markup >= 0.5.1 && < 0.6,
218− bytestring >= 0.10 && < 0.11,
218+ bytestring >= 0.9 && < 0.11,
219 citeproc-hs >= 0.3.2 && < 0.4,
219 citeproc-hs >= 0.3.2 && < 0.4,
220 containers >= 0.3 && < 0.6,
220 containers >= 0.3 && < 0.6,
221 cryptohash >= 0.7 && < 0.9,
221 cryptohash >= 0.7 && < 0.9,
src/Hakyll/Check.hs+17−5
@@ -109,8 +109,8 @@ runChecker checker config verbosity check' = do
109checkDestination :: Checker ()
109checkDestination :: Checker ()
110checkDestination = do
110checkDestination = do
111 config <- checkerConfig <$> ask
111 config <- checkerConfig <$> ask
112− files <- liftIO $
112+ files <- liftIO $ getRecursiveContents
113− getRecursiveContents (const False) (destinationDirectory config)
113+ (const $ return False) (destinationDirectory config)
114
114
115 let htmls =
115 let htmls =
116 [ destinationDirectory config </> file
116 [ destinationDirectory config </> file
@@ -137,9 +137,14 @@ checkFile filePath = do
137--------------------------------------------------------------------------------
137--------------------------------------------------------------------------------
138checkUrl :: FilePath -> String -> Checker ()
138checkUrl :: FilePath -> String -> Checker ()
139checkUrl filePath url
139checkUrl filePath url
140− | isExternal url = checkExternalUrl url
140+ | isExternal url = checkExternalUrl url
141− | "mailto:" `isPrefixOf` url = ok url
141+ | hasProtocol url = skip "Unknown protocol, skipping"
142− | otherwise = checkInternalUrl filePath url
142+ | otherwise = checkInternalUrl filePath url
143+ where
144+ validProtoChars = ['A'..'Z'] ++ ['a'..'z'] ++ ['0'..'9'] ++ "+-."
145+ hasProtocol str = case break (== ':') str of
146+ (proto, ':' : _) -> all (`elem` validProtoChars) proto
147+ _ -> False
143
148
144
149
145--------------------------------------------------------------------------------
150--------------------------------------------------------------------------------
@@ -147,6 +152,13 @@ ok :: String -> Checker ()
147ok _ = tell $ mempty {checkerOk = 1}
152ok _ = tell $ mempty {checkerOk = 1}
148
153
149
154
155+--------------------------------------------------------------------------------
156+skip :: String -> Checker ()
157+skip reason = do
158+ logger <- checkerLogger <$> ask
159+ Logger.debug logger $ reason
160+ tell $ mempty {checkerOk = 1}
161+
150--------------------------------------------------------------------------------
162--------------------------------------------------------------------------------
151faulty :: String -> Checker ()
163faulty :: String -> Checker ()
152faulty url = do
164faulty url = do
src/Hakyll/Core/Compiler.hs+10−1
@@ -10,7 +10,7 @@ module Hakyll.Core.Compiler
10 , getResourceBody
10 , getResourceBody
11 , getResourceString
11 , getResourceString
12 , getResourceLBS
12 , getResourceLBS
13− , getResourceWith
13+ , getResourceFilePath
14
14
15 , Internal.Snapshot
15 , Internal.Snapshot
16 , saveSnapshot
16 , saveSnapshot
@@ -98,6 +98,15 @@ getResourceLBS :: Compiler (Item ByteString)
98getResourceLBS = getResourceWith resourceLBS
98getResourceLBS = getResourceWith resourceLBS
99
99
100
100
101+--------------------------------------------------------------------------------
102+-- | Get the file path of the resource we are compiling
103+getResourceFilePath :: Compiler FilePath
104+getResourceFilePath = do
105+ provider <- compilerProvider <$> compilerAsk
106+ id' <- compilerUnderlying <$> compilerAsk
107+ return $ resourceFilePath provider id'
108+
109+
101--------------------------------------------------------------------------------
110--------------------------------------------------------------------------------
102-- | Overloadable function for 'getResourceString' and 'getResourceLBS'
111-- | Overloadable function for 'getResourceString' and 'getResourceLBS'
103getResourceWith :: (Provider -> Identifier -> IO a) -> Compiler (Item a)
112getResourceWith :: (Provider -> Identifier -> IO a) -> Compiler (Item a)
src/Hakyll/Core/Configuration.hs+26−12
@@ -8,11 +8,13 @@ module Hakyll.Core.Configuration
8
8
9
9
10--------------------------------------------------------------------------------
10--------------------------------------------------------------------------------
11−import Control.Monad (void)
11+import Control.Monad (void)
12−import Data.Default (Default(..))
12+import Data.Default (Default (..))
13−import Data.List (isPrefixOf, isSuffixOf)
13+import Data.List (isPrefixOf, isSuffixOf)
14+import System.Directory (canonicalizePath)
14−import System.FilePath (normalise, takeFileName)
15+import System.FilePath (isAbsolute, normalise, takeFileName)
16+import System.IO.Error (catchIOError)
15−import System.Process (system)
17+import System.Process (system)
16
18
17
19
18--------------------------------------------------------------------------------
20--------------------------------------------------------------------------------
@@ -99,11 +101,23 @@ defaultConfiguration = Configuration
99
101
100--------------------------------------------------------------------------------
102--------------------------------------------------------------------------------
101-- | Check if a file should be ignored
103-- | Check if a file should be ignored
102−shouldIgnoreFile :: Configuration -> FilePath -> Bool
104+shouldIgnoreFile :: Configuration -> FilePath -> IO Bool
103−shouldIgnoreFile conf path =
105+shouldIgnoreFile conf path = orM
104− destinationDirectory conf `isPrefixOf` path' ||
106+ [ inDir (destinationDirectory conf)
105− storeDirectory conf `isPrefixOf` path' ||
107+ , inDir (storeDirectory conf)
106− tmpDirectory conf `isPrefixOf` path' ||
108+ , inDir (tmpDirectory conf)
107− ignoreFile conf path'
109+ , return (ignoreFile conf path')
110+ ]
108 where
111 where
109− path' = normalise path
112+ path' = normalise path
113+ absolute = isAbsolute path
114+
115+ inDir dir
116+ | absolute = do
117+ dir' <- catchIOError (canonicalizePath dir) (const $ return dir)
118+ return $ dir' `isPrefixOf` path'
119+ | otherwise = return $ dir `isPrefixOf` path'
120+
121+ orM :: [IO Bool] -> IO Bool
122+ orM [] = return False
123+ orM (x : xs) = x >>= \b -> if b then return True else orM xs
src/Hakyll/Core/Provider.hs+4−4
@@ -31,10 +31,10 @@ import Hakyll.Core.Store (Store)
31
31
32--------------------------------------------------------------------------------
32--------------------------------------------------------------------------------
33-- | Create a resource provider
33-- | Create a resource provider
34−newProvider :: Store -- ^ Store to use
34+newProvider :: Store -- ^ Store to use
35− -> (FilePath -> Bool) -- ^ Should we ignore this file?
35+ -> (FilePath -> IO Bool) -- ^ Should we ignore this file?
36− -> FilePath -- ^ Search directory
36+ -> FilePath -- ^ Search directory
37− -> IO Internal.Provider -- ^ Resulting provider
37+ -> IO Internal.Provider -- ^ Resulting provider
38newProvider store ignore directory = do
38newProvider store ignore directory = do
39 -- Delete metadata cache where necessary
39 -- Delete metadata cache where necessary
40 p <- Internal.newProvider store ignore directory
40 p <- Internal.newProvider store ignore directory
src/Hakyll/Core/Provider/Internal.hs+4−4
@@ -103,10 +103,10 @@ data Provider = Provider
103
103
104--------------------------------------------------------------------------------
104--------------------------------------------------------------------------------
105-- | Create a resource provider
105-- | Create a resource provider
106−newProvider :: Store -- ^ Store to use
106+newProvider :: Store -- ^ Store to use
107− -> (FilePath -> Bool) -- ^ Should we ignore this file?
107+ -> (FilePath -> IO Bool) -- ^ Should we ignore this file?
108− -> FilePath -- ^ Search directory
108+ -> FilePath -- ^ Search directory
109− -> IO Provider -- ^ Resulting provider
109+ -> IO Provider -- ^ Resulting provider
110newProvider store ignore directory = do
110newProvider store ignore directory = do
111 list <- map fromFilePath <$> getRecursiveContents ignore directory
111 list <- map fromFilePath <$> getRecursiveContents ignore directory
112 let universe = S.fromList list
112 let universe = S.fromList list
src/Hakyll/Core/UnixFilter.hs+10−7
@@ -9,7 +9,7 @@ module Hakyll.Core.UnixFilter
9--------------------------------------------------------------------------------
9--------------------------------------------------------------------------------
10import Control.Concurrent (forkIO)
10import Control.Concurrent (forkIO)
11import Control.Concurrent.MVar (newEmptyMVar, putMVar, takeMVar)
11import Control.Concurrent.MVar (newEmptyMVar, putMVar, takeMVar)
12−import Control.DeepSeq (NFData, deepseq)
12+import Control.DeepSeq (deepseq)
13import Control.Monad (forM_)
13import Control.Monad (forM_)
14import Data.ByteString.Lazy (ByteString)
14import Data.ByteString.Lazy (ByteString)
15import qualified Data.ByteString.Lazy as LB
15import qualified Data.ByteString.Lazy as LB
@@ -57,7 +57,8 @@ unixFilter = unixFilterWith writer reader
57 hPutStr handle input
57 hPutStr handle input
58 reader handle = do
58 reader handle = do
59 hSetEncoding handle localeEncoding
59 hSetEncoding handle localeEncoding
60− hGetContents handle
60+ out <- hGetContents handle
61+ deepseq out (return out)
61
62
62
63
63--------------------------------------------------------------------------------
64--------------------------------------------------------------------------------
@@ -70,12 +71,14 @@ unixFilterLBS :: String -- ^ Program name
70 -> [String] -- ^ Program args
71 -> [String] -- ^ Program args
71 -> ByteString -- ^ Program input
72 -> ByteString -- ^ Program input
72 -> Compiler ByteString -- ^ Program output
73 -> Compiler ByteString -- ^ Program output
73−unixFilterLBS = unixFilterWith LB.hPutStr LB.hGetContents
74+unixFilterLBS = unixFilterWith LB.hPutStr $ \handle -> do
75+ out <- LB.hGetContents handle
76+ LB.length out `seq` return out
74
77
75
78
76--------------------------------------------------------------------------------
79--------------------------------------------------------------------------------
77-- | Overloaded compiler
80-- | Overloaded compiler
78−unixFilterWith :: (Monoid o, NFData o)
81+unixFilterWith :: Monoid o
79 => (Handle -> i -> IO ()) -- ^ Writer
82 => (Handle -> i -> IO ()) -- ^ Writer
80 -> (Handle -> IO o) -- ^ Reader
83 -> (Handle -> IO o) -- ^ Reader
81 -> String -- ^ Program name
84 -> String -- ^ Program name
@@ -96,7 +99,7 @@ unixFilterWith writer reader programName args input = do
96
99
97--------------------------------------------------------------------------------
100--------------------------------------------------------------------------------
98-- | Internally used function
101-- | Internally used function
99−unixFilterIO :: (Monoid o, NFData o)
102+unixFilterIO :: Monoid o
100 => (Handle -> i -> IO ())
103 => (Handle -> i -> IO ())
101 -> (Handle -> IO o)
104 -> (Handle -> IO o)
102 -> String
105 -> String
@@ -122,14 +125,14 @@ unixFilterIO writer reader programName args input = do
122 -- Read from stdout
125 -- Read from stdout
123 _ <- forkIO $ do
126 _ <- forkIO $ do
124 out <- reader outh
127 out <- reader outh
125− deepseq out (hClose outh)
128+ hClose outh
126 writeIORef outRef out
129 writeIORef outRef out
127 putMVar lock ()
130 putMVar lock ()
128
131
129 -- Read from stderr
132 -- Read from stderr
130 _ <- forkIO $ do
133 _ <- forkIO $ do
131 err <- hGetContents errh
134 err <- hGetContents errh
132− deepseq err (hClose errh)
135+ hClose errh
133 writeIORef errRef err
136 writeIORef errRef err
134 putMVar lock ()
137 putMVar lock ()
135
138
src/Hakyll/Core/Util/File.hs+9−6
@@ -9,7 +9,7 @@ module Hakyll.Core.Util.File
9
9
10--------------------------------------------------------------------------------
10--------------------------------------------------------------------------------
11import Control.Applicative ((<$>))
11import Control.Applicative ((<$>))
12−import Control.Monad (forM, when)
12+import Control.Monad (filterM, forM, when)
13import System.Directory (createDirectoryIfMissing,
13import System.Directory (createDirectoryIfMissing,
14 doesDirectoryExist, getDirectoryContents,
14 doesDirectoryExist, getDirectoryContents,
15 removeDirectoryRecursive)
15 removeDirectoryRecursive)
@@ -25,18 +25,21 @@ makeDirectories = createDirectoryIfMissing True . takeDirectory
25
25
26--------------------------------------------------------------------------------
26--------------------------------------------------------------------------------
27-- | Get all contents of a directory.
27-- | Get all contents of a directory.
28−getRecursiveContents :: (FilePath -> Bool) -- ^ Ignore this file/directory
28+getRecursiveContents :: (FilePath -> IO Bool) -- ^ Ignore this file/directory
29− -> FilePath -- ^ Directory to search
29+ -> FilePath -- ^ Directory to search
30− -> IO [FilePath] -- ^ List of files found
30+ -> IO [FilePath] -- ^ List of files found
31getRecursiveContents ignore top = go ""
31getRecursiveContents ignore top = go ""
32 where
32 where
33− isProper x = notElem x [".", ".."] && not (ignore x)
33+ isProper x
34+ | x `elem` [".", ".."] = return False
35+ | otherwise = not <$> ignore x
36+
34 go dir = do
37 go dir = do
35 dirExists <- doesDirectoryExist (top </> dir)
38 dirExists <- doesDirectoryExist (top </> dir)
36 if not dirExists
39 if not dirExists
37 then return []
40 then return []
38 else do
41 else do
39− names <- filter isProper <$> getDirectoryContents (top </> dir)
42+ names <- filterM isProper =<< getDirectoryContents (top </> dir)
40 paths <- forM names $ \name -> do
43 paths <- forM names $ \name -> do
41 let rel = dir </> name
44 let rel = dir </> name
42 isDirectory <- doesDirectoryExist (top </> rel)
45 isDirectory <- doesDirectoryExist (top </> rel)
src/Hakyll/Init.hs+1−1
@@ -23,7 +23,7 @@ main = do
23 progName <- getProgName
23 progName <- getProgName
24 args <- getArgs
24 args <- getArgs
25 srcDir <- getDataFileName "example"
25 srcDir <- getDataFileName "example"
26− files <- getRecursiveContents (const False) srcDir
26+ files <- getRecursiveContents (const $ return False) srcDir
27
27
28 case args of
28 case args of
29 [dstDir] -> forM_ files $ \file -> do
29 [dstDir] -> forM_ files $ \file -> do
tests/TestSuite/Util.hs+1−1
@@ -46,7 +46,7 @@ newTestStore = Store.new True $ storeDirectory testConfiguration
46
46
47--------------------------------------------------------------------------------
47--------------------------------------------------------------------------------
48newTestProvider :: Store -> IO Provider
48newTestProvider :: Store -> IO Provider
49−newTestProvider store = newProvider store (const False) $
49+newTestProvider store = newProvider store (const $ return False) $
50 providerDirectory testConfiguration
50 providerDirectory testConfiguration
51
51
52
52
web/examples.markdown+2
@@ -29,6 +29,8 @@ this list. This list has no particular ordering.
29 [source](https://github.com/dannysu/hakyll-blog)
29 [source](https://github.com/dannysu/hakyll-blog)
30- <http://meta.plasm.us/>,
30- <http://meta.plasm.us/>,
31 [source](https://github.com/travisbrown/metaplasm)
31 [source](https://github.com/travisbrown/metaplasm)
32+- <http://www.web2day-nantes.org/>,
33+ [source](https://github.com/CompanyCampus/web2day2013)
32
34
33## Hakyll 3.X
35## Hakyll 3.X
34
36