1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
--------------------------------------------------------------------------------
-- | Exports a datastructure for the top-level hakyll configuration
module Hakyll.Core.Configuration
( Configuration (..)
, shouldIgnoreFile
, defaultConfiguration
) where
--------------------------------------------------------------------------------
import Data.Default (Default (..))
import Data.List (isPrefixOf, isSuffixOf)
import System.Directory (canonicalizePath)
import System.Exit (ExitCode)
import System.FilePath (isAbsolute, normalise, takeFileName)
import System.IO.Error (catchIOError)
import System.Process (system)
--------------------------------------------------------------------------------
data Configuration = Configuration
{ -- | Directory in which the output written
destinationDirectory :: FilePath
, -- | Directory where hakyll's internal store is kept
storeDirectory :: FilePath
, -- | Directory in which some temporary files will be kept
tmpDirectory :: FilePath
, -- | Directory where hakyll finds the files to compile. This is @.@ by
-- default.
providerDirectory :: FilePath
, -- | Function to determine ignored files
--
-- In 'defaultConfiguration', the following files are ignored:
--
-- * files starting with a @.@
--
-- * files starting with a @#@
--
-- * files ending with a @~@
--
-- * files ending with @.swp@
--
-- Note that the files in 'destinationDirectory' and 'storeDirectory' will
-- also be ignored. Note that this is the configuration parameter, if you
-- want to use the test, you should use 'shouldIgnoreFile'.
--
ignoreFile :: FilePath -> Bool
, -- | Here, you can plug in a system command to upload/deploy your site.
--
-- Example:
--
-- > rsync -ave 'ssh -p 2217' _site jaspervdj@jaspervdj.be:hakyll
--
-- You can execute this by using
--
-- > ./site deploy
--
deployCommand :: String
, -- | Function to deploy the site from Haskell.
--
-- By default, this command executes the shell command stored in
-- 'deployCommand'. If you override it, 'deployCommand' will not
-- be used implicitely.
--
-- The 'Configuration' object is passed as a parameter to this
-- function.
--
deploySite :: Configuration -> IO ExitCode
, -- | Use an in-memory cache for items. This is faster but uses more
-- memory.
inMemoryCache :: Bool
, -- | Override default port for preview server. Default is 8000.
-- One can also override the port as a command line argument:
-- ./site preview -p 1234
previewPort :: Int
}
--------------------------------------------------------------------------------
instance Default Configuration where
def = defaultConfiguration
--------------------------------------------------------------------------------
-- | Default configuration for a hakyll application
defaultConfiguration :: Configuration
defaultConfiguration = Configuration
{ destinationDirectory = "_site"
, storeDirectory = "_cache"
, tmpDirectory = "_cache/tmp"
, providerDirectory = "."
, ignoreFile = ignoreFile'
, deployCommand = "echo 'No deploy command specified' && exit 1"
, deploySite = system . deployCommand
, inMemoryCache = True
, previewPort = 8000
}
where
ignoreFile' path
| "." `isPrefixOf` fileName = True
| "#" `isPrefixOf` fileName = True
| "~" `isSuffixOf` fileName = True
| ".swp" `isSuffixOf` fileName = True
| otherwise = False
where
fileName = takeFileName path
--------------------------------------------------------------------------------
-- | Check if a file should be ignored
shouldIgnoreFile :: Configuration -> FilePath -> IO Bool
shouldIgnoreFile conf path = orM
[ inDir (destinationDirectory conf)
, inDir (storeDirectory conf)
, inDir (tmpDirectory conf)
, return (ignoreFile conf path')
]
where
path' = normalise path
absolute = isAbsolute path
inDir dir
| absolute = do
dir' <- catchIOError (canonicalizePath dir) (const $ return dir)
return $ dir' `isPrefixOf` path'
| otherwise = return $ dir `isPrefixOf` path'
orM :: [IO Bool] -> IO Bool
orM [] = return False
orM (x : xs) = x >>= \b -> if b then return True else orM xs
|