on master help sign in
Just messing around
ede51e8Jasper Van der Jeugt
src/Hakyll/Core/Dependencies.hsnew file+59
@@ -0,0 +1,59 @@
1+--------------------------------------------------------------------------------
2+{-# LANGUAGE BangPatterns #-}
3+module Hakyll.Core.Dependencies
4+ (
5+ ) where
6+
7+
8+--------------------------------------------------------------------------------
9+import Data.List (foldl')
10+import Data.Map (Map)
11+import qualified Data.Map as M
12+import Data.Set (Set)
13+import qualified Data.Set as S
14+
15+
16+--------------------------------------------------------------------------------
17+import Hakyll.Core.Identifier
18+import Hakyll.Core.Identifier.Pattern
19+
20+
21+--------------------------------------------------------------------------------
22+data Dependency
23+ = Pattern (Pattern ()) [Identifier ()]
24+ | Identifier (Identifier ())
25+ deriving (Show)
26+
27+
28+--------------------------------------------------------------------------------
29+type DependencyFacts = Map (Identifier ()) [Dependency]
30+
31+
32+--------------------------------------------------------------------------------
33+outOfDate
34+ :: [Identifier ()] -- ^ All known identifiers
35+ -> Set (Identifier ()) -- ^ Initially out-of-date resources
36+ -> DependencyFacts -- ^ Old dependency facts
37+ -> (Set (Identifier ()), DependencyFacts)
38+outOfDate universe ood oldFacts = (ood, oldFacts)
39+
40+
41+--------------------------------------------------------------------------------
42+-- | Determine patterns with changed results
43+changedPatterns
44+ :: [Identifier ()]
45+ -> DependencyFacts
46+ -> (Set (Identifier ()), DependencyFacts)
47+changedPatterns universe facts =
48+ M.foldlWithKey' changed (S.empty, facts) facts
49+ where
50+ changed (!o, !f) id' deps =
51+ let (o', deps') = foldr (changed' id') (o, []) deps
52+ in (o', M.insert id' deps' f)
53+
54+ changed' _ (Identifier i) (o, d) = (o, Identifier i : d)
55+ changed' id' (Pattern p ls) (o, d)
56+ | ls == ls' = (o, Pattern p ls : d)
57+ | otherwise = (S.insert id' o, Pattern p ls' : d)
58+ where
59+ ls' = filterMatches p universe
src/Hakyll/Core/Identifier.hs+37−13
@@ -36,30 +36,36 @@ module Hakyll.Core.Identifier
36 , fromFilePath
36 , fromFilePath
37 , toFilePath
37 , toFilePath
38 , castIdentifier
38 , castIdentifier
39+ , identifierVersion
40+ , setVersion
39 ) where
41 ) where
40
42
41
43
42--------------------------------------------------------------------------------
44--------------------------------------------------------------------------------
43−import Control.DeepSeq (NFData)
45+import Control.Applicative ((<$>), (<*>))
46+import Control.DeepSeq (NFData (..))
44−import Data.List (intercalate)
47+import Data.List (intercalate)
45−import System.FilePath (dropTrailingPathSeparator, splitPath)
48+import System.FilePath (dropTrailingPathSeparator, splitPath)
46
49
47
50
48--------------------------------------------------------------------------------
51--------------------------------------------------------------------------------
49−import Data.Binary (Binary)
52+import Data.Binary (Binary (..))
50−import Data.Typeable (Typeable)
53+import Data.Typeable (Typeable)
51−import GHC.Exts (IsString, fromString)
54+import GHC.Exts (IsString, fromString)
52
55
53
56
54--------------------------------------------------------------------------------
57--------------------------------------------------------------------------------
55-- | An identifier used to uniquely identify a value
58-- | An identifier used to uniquely identify a value
56−newtype Identifier a = Identifier {unIdentifier :: String}
59+data Identifier a = Identifier
60+ { identifierVersion :: Maybe String
61+ , identifierPath :: String
57− deriving (Binary, Eq, NFData, Ord, Typeable)
62+ } deriving (Eq, Ord, Typeable)
58
63
59
64
60--------------------------------------------------------------------------------
65--------------------------------------------------------------------------------
61−instance Show (Identifier a) where
66+instance Binary (Identifier a) where
62− show = toFilePath
67+ put (Identifier v p) = put v >> put p
68+ get = Identifier <$> get <*> get
63
69
64
70
65--------------------------------------------------------------------------------
71--------------------------------------------------------------------------------
@@ -67,10 +73,23 @@ instance IsString (Identifier a) where
67 fromString = fromFilePath
73 fromString = fromFilePath
68
74
69
75
76+--------------------------------------------------------------------------------
77+instance NFData (Identifier a) where
78+ rnf (Identifier v p) = rnf v `seq` rnf p `seq` ()
79+
80+
81+--------------------------------------------------------------------------------
82+instance Show (Identifier a) where
83+ show i = case identifierVersion i of
84+ Nothing -> toFilePath i
85+ Just v -> toFilePath i ++ " (" ++ v ++ ")"
86+
87+
70--------------------------------------------------------------------------------
88--------------------------------------------------------------------------------
71-- | Parse an identifier from a string
89-- | Parse an identifier from a string
72fromFilePath :: String -> Identifier a
90fromFilePath :: String -> Identifier a
91+fromFilePath = Identifier Nothing .
73−fromFilePath = Identifier . intercalate "/" . filter (not . null) . split'
92+ intercalate "/" . filter (not . null) . split'
74 where
93 where
75 split' = map dropTrailingPathSeparator . splitPath
94 split' = map dropTrailingPathSeparator . splitPath
76
95
@@ -78,11 +97,16 @@ fromFilePath = Identifier . intercalate "/" . filter (not . null) . split'
78--------------------------------------------------------------------------------
97--------------------------------------------------------------------------------
79-- | Convert an identifier to a relative 'FilePath'
98-- | Convert an identifier to a relative 'FilePath'
80toFilePath :: Identifier a -> FilePath
99toFilePath :: Identifier a -> FilePath
81−toFilePath = unIdentifier
100+toFilePath = identifierPath
82
101
83
102
84--------------------------------------------------------------------------------
103--------------------------------------------------------------------------------
85-- | Discard the phantom type parameter of an identifier
104-- | Discard the phantom type parameter of an identifier
86castIdentifier :: Identifier a -> Identifier b
105castIdentifier :: Identifier a -> Identifier b
87−castIdentifier (Identifier x) = Identifier x
106+castIdentifier (Identifier v p) = Identifier v p
88{-# INLINE castIdentifier #-}
107{-# INLINE castIdentifier #-}
108+
109+
110+--------------------------------------------------------------------------------
111+setVersion :: Maybe String -> Identifier a -> Identifier a
112+setVersion v i = i {identifierVersion = v}
src/Hakyll/Core/Identifier/Pattern.hs+15−2
@@ -46,6 +46,7 @@ module Hakyll.Core.Identifier.Pattern
46
46
47 -- * Manipulating patterns
47 -- * Manipulating patterns
48 , complement
48 , complement
49+ , withVersion
49 , castPattern
50 , castPattern
50
51
51 -- * Applying patterns
52 -- * Applying patterns
@@ -109,6 +110,7 @@ data Pattern a
109 | Glob [GlobComponent]
110 | Glob [GlobComponent]
110 | List [Identifier a] -- TODO Maybe use a set here
111 | List [Identifier a] -- TODO Maybe use a set here
111 | Regex String
112 | Regex String
113+ | Version (Maybe String)
112 deriving (Show)
114 deriving (Show)
113
115
114
116
@@ -120,6 +122,7 @@ instance Binary (Pattern a) where
120 put (Glob g) = putWord8 3 >> put g
122 put (Glob g) = putWord8 3 >> put g
121 put (List is) = putWord8 4 >> put is
123 put (List is) = putWord8 4 >> put is
122 put (Regex r) = putWord8 5 >> put r
124 put (Regex r) = putWord8 5 >> put r
125+ put (Version v) = putWord8 6 >> put v
123
126
124 get = getWord8 >>= \t -> case t of
127 get = getWord8 >>= \t -> case t of
125 0 -> pure Everything
128 0 -> pure Everything
@@ -127,7 +130,8 @@ instance Binary (Pattern a) where
127 2 -> And <$> get <*> get
130 2 -> And <$> get <*> get
128 3 -> Glob <$> get
131 3 -> Glob <$> get
129 4 -> List <$> get
132 4 -> List <$> get
130− _ -> Regex <$> get
133+ 5 -> Regex <$> get
134+ _ -> Version <$> get
131
135
132
136
133--------------------------------------------------------------------------------
137--------------------------------------------------------------------------------
@@ -177,11 +181,18 @@ fromRegex = Regex
177-- > complement "foo/bar.html"
181-- > complement "foo/bar.html"
178--
182--
179-- will match /anything/ except @\"foo\/bar.html\"@
183-- will match /anything/ except @\"foo\/bar.html\"@
180−--
181complement :: Pattern a -> Pattern a
184complement :: Pattern a -> Pattern a
182complement = Complement
185complement = Complement
183
186
184
187
188+--------------------------------------------------------------------------------
189+-- | Specify a version, e.g.
190+--
191+-- > "foo/*.markdown" `withVersion` "pdf"
192+withVersion :: Pattern a -> String -> Pattern a
193+withVersion p v = And p $ Version $ Just v
194+
195+
185--------------------------------------------------------------------------------
196--------------------------------------------------------------------------------
186-- | Discard the phantom type parameter
197-- | Discard the phantom type parameter
187castPattern :: Pattern a -> Pattern b
198castPattern :: Pattern a -> Pattern b
@@ -191,6 +202,7 @@ castPattern (And x y) = And (castPattern x) (castPattern y)
191castPattern (Glob g) = Glob g
202castPattern (Glob g) = Glob g
192castPattern (List l) = List $ map castIdentifier l
203castPattern (List l) = List $ map castIdentifier l
193castPattern (Regex r) = Regex r
204castPattern (Regex r) = Regex r
205+castPattern (Version v) = Version v
194
206
195
207
196--------------------------------------------------------------------------------
208--------------------------------------------------------------------------------
@@ -202,6 +214,7 @@ matches (And x y) i = matches x i && matches y i
202matches (Glob p) i = isJust $ capture (Glob p) i
214matches (Glob p) i = isJust $ capture (Glob p) i
203matches (List l) i = i `elem` l
215matches (List l) i = i `elem` l
204matches (Regex r) i = toFilePath i =~ r
216matches (Regex r) i = toFilePath i =~ r
217+matches (Version v) i = identifierVersion i == v
205
218
206
219
207--------------------------------------------------------------------------------
220--------------------------------------------------------------------------------