aboutsummaryrefslogtreecommitdiff
path: root/compiler/src
diff options
context:
space:
mode:
authorpacien2020-01-30 16:03:54 +0100
committerpacien2020-01-31 18:09:50 +0100
commit4fde03c7654dcdad11a8c91ba2bcbb2706695e11 (patch)
tree704f521b3c55c1753fef25d7e81c733692dae40e /compiler/src
parent245fee3fe5abdc6ad14513ef6522446aba4c905a (diff)
downloadldgallery-4fde03c7654dcdad11a8c91ba2bcbb2706695e11.tar.gz
compiler: properly exclude out directory
Use canonical paths to exclude the output directory if it is located inside the input directory instead of guessing based on special files. GitHub: closes #54
Diffstat (limited to 'compiler/src')
-rw-r--r--compiler/src/Compiler.hs20
-rw-r--r--compiler/src/Files.hs49
2 files changed, 39 insertions, 30 deletions
diff --git a/compiler/src/Compiler.hs b/compiler/src/Compiler.hs
index 8819ffc..d392f74 100644
--- a/compiler/src/Compiler.hs
+++ b/compiler/src/Compiler.hs
@@ -26,6 +26,7 @@ import Control.Monad (liftM2)
26import Data.List (any) 26import Data.List (any)
27import System.FilePath ((</>)) 27import System.FilePath ((</>))
28import qualified System.FilePath.Glob as Glob 28import qualified System.FilePath.Glob as Glob
29import System.Directory (canonicalizePath)
29 30
30import Data.Aeson (ToJSON) 31import Data.Aeson (ToJSON)
31import qualified Data.Aeson as JSON 32import qualified Data.Aeson as JSON
@@ -52,9 +53,6 @@ galleryConf = "gallery.yaml"
52indexFile :: String 53indexFile :: String
53indexFile = "index.json" 54indexFile = "index.json"
54 55
55viewerMainFile :: String
56viewerMainFile = "index.html"
57
58viewerConfFile :: String 56viewerConfFile :: String
59viewerConfFile = "viewer.json" 57viewerConfFile = "viewer.json"
60 58
@@ -72,11 +70,11 @@ writeJSON outputPath object =
72 ensureParentDir JSON.encodeFile outputPath object 70 ensureParentDir JSON.encodeFile outputPath object
73 71
74 72
75galleryDirFilter :: CompilerConfig -> FSNode -> Bool 73galleryDirFilter :: CompilerConfig -> FilePath -> FSNode -> Bool
76galleryDirFilter config = 74galleryDirFilter config outputDir =
77 (not . isHidden) 75 (not . isHidden)
76 &&& (not . isOutputGallery)
78 &&& (not . matchesFile (== galleryConf)) 77 &&& (not . matchesFile (== galleryConf))
79 &&& (not . containsOutputGallery)
80 &&& ((matchesDir $ anyPattern $ includedDirectories config) ||| 78 &&& ((matchesDir $ anyPattern $ includedDirectories config) |||
81 (matchesFile $ anyPattern $ includedFiles config)) 79 (matchesFile $ anyPattern $ includedFiles config))
82 &&& (not . ((matchesDir $ anyPattern $ excludedDirectories config) ||| 80 &&& (not . ((matchesDir $ anyPattern $ excludedDirectories config) |||
@@ -97,10 +95,9 @@ galleryDirFilter config =
97 anyPattern :: [String] -> FileName -> Bool 95 anyPattern :: [String] -> FileName -> Bool
98 anyPattern patterns filename = any (flip Glob.match filename) (map Glob.compile patterns) 96 anyPattern patterns filename = any (flip Glob.match filename) (map Glob.compile patterns)
99 97
100 containsOutputGallery :: FSNode -> Bool 98 isOutputGallery :: FSNode -> Bool
101 containsOutputGallery File{} = False 99 isOutputGallery Dir{canonicalPath} = canonicalPath == outputDir
102 containsOutputGallery Dir{items} = 100 isOutputGallery File{} = False
103 any (matchesFile (== indexFile) ||| matchesFile (== viewerMainFile)) items
104 101
105 102
106compileGallery :: FilePath -> FilePath -> Bool -> Bool -> IO () 103compileGallery :: FilePath -> FilePath -> Bool -> Bool -> IO ()
@@ -110,7 +107,8 @@ compileGallery inputDirPath outputDirPath rebuildAll cleanOutput =
110 let config = compiler fullConfig 107 let config = compiler fullConfig
111 108
112 inputDir <- readDirectory inputDirPath 109 inputDir <- readDirectory inputDirPath
113 let sourceFilter = galleryDirFilter config 110 canonicalOutPath <- canonicalizePath outputDirPath
111 let sourceFilter = galleryDirFilter config canonicalOutPath
114 let sourceTree = filterDir sourceFilter inputDir 112 let sourceTree = filterDir sourceFilter inputDir
115 inputTree <- readInputTree sourceTree 113 inputTree <- readInputTree sourceTree
116 114
diff --git a/compiler/src/Files.hs b/compiler/src/Files.hs
index 41fc5a8..8ea943f 100644
--- a/compiler/src/Files.hs
+++ b/compiler/src/Files.hs
@@ -29,7 +29,6 @@ module Files
29 29
30 30
31import Control.Monad (mapM) 31import Control.Monad (mapM)
32import Data.Bool (bool)
33import Data.List (isPrefixOf, length, subsequences) 32import Data.List (isPrefixOf, length, subsequences)
34import Data.Function ((&)) 33import Data.Function ((&))
35import Data.Text (pack) 34import Data.Text (pack)
@@ -39,6 +38,7 @@ import qualified Data.Aeson as JSON
39import System.Directory 38import System.Directory
40 ( doesDirectoryExist 39 ( doesDirectoryExist
41 , doesPathExist 40 , doesPathExist
41 , canonicalizePath
42 , getModificationTime 42 , getModificationTime
43 , listDirectory 43 , listDirectory
44 , createDirectoryIfMissing 44 , createDirectoryIfMissing
@@ -94,8 +94,13 @@ webPath (Path path) = System.FilePath.Posix.joinPath $ reverse path
94 94
95 95
96data FSNode = 96data FSNode =
97 File { path :: Path } 97 File
98 | Dir { path :: Path, items :: [FSNode] } 98 { path :: Path
99 , canonicalPath :: FilePath }
100 | Dir
101 { path :: Path
102 , canonicalPath :: FilePath
103 , items :: [FSNode] }
99 deriving Show 104 deriving Show
100 105
101data AnchoredFSNode = AnchoredFSNode 106data AnchoredFSNode = AnchoredFSNode
@@ -115,8 +120,8 @@ isHidden = hiddenName . nodeName
115 120
116-- | DFS with intermediate dirs first. 121-- | DFS with intermediate dirs first.
117flattenDir :: FSNode -> [FSNode] 122flattenDir :: FSNode -> [FSNode]
118flattenDir file@(File _) = [file] 123flattenDir file@File{} = [file]
119flattenDir dir@(Dir _ items) = dir:(concatMap flattenDir items) 124flattenDir dir@Dir{items} = dir:(concatMap flattenDir items)
120 125
121-- | Filters a dir tree. The root is always returned. 126-- | Filters a dir tree. The root is always returned.
122filterDir :: (FSNode -> Bool) -> AnchoredFSNode -> AnchoredFSNode 127filterDir :: (FSNode -> Bool) -> AnchoredFSNode -> AnchoredFSNode
@@ -124,35 +129,41 @@ filterDir cond (AnchoredFSNode anchor root) =
124 AnchoredFSNode anchor (filterNode root) 129 AnchoredFSNode anchor (filterNode root)
125 where 130 where
126 filterNode :: FSNode -> FSNode 131 filterNode :: FSNode -> FSNode
127 filterNode file@(File _) = file 132 filterNode file@File{} = file
128 filterNode (Dir path items) = 133 filterNode Dir{path, canonicalPath, items} =
129 filter cond items & map filterNode & Dir path 134 filter cond items & map filterNode & Dir path canonicalPath
130 135
131readDirectory :: LocalPath -> IO AnchoredFSNode 136readDirectory :: LocalPath -> IO AnchoredFSNode
132readDirectory root = mkNode (Path []) >>= return . AnchoredFSNode root 137readDirectory root = mkNode (Path []) >>= return . AnchoredFSNode root
133 where 138 where
134 mkNode :: Path -> IO FSNode 139 mkNode :: Path -> IO FSNode
135 mkNode path = 140 mkNode path =
136 (doesDirectoryExist $ localPath (root /> path)) 141 do
137 >>= bool (mkFileNode path) (mkDirNode path) 142 let relPath = localPath (root /> path)
138 143 canonicalPath <- canonicalizePath relPath
139 mkFileNode :: Path -> IO FSNode 144 isDir <- doesDirectoryExist relPath
140 mkFileNode path = return $ File path 145 if isDir then
141 146 mkDirNode path canonicalPath
142 mkDirNode :: Path -> IO FSNode 147 else
143 mkDirNode path = 148 mkFileNode path canonicalPath
149
150 mkFileNode :: Path -> FilePath -> IO FSNode
151 mkFileNode path canonicalPath = return $ File path canonicalPath
152
153 mkDirNode :: Path -> FilePath -> IO FSNode
154 mkDirNode path canonicalPath =
144 (listDirectory $ localPath (root /> path)) 155 (listDirectory $ localPath (root /> path))
145 >>= mapM (mkNode . ((</) path)) 156 >>= mapM (mkNode . ((</) path))
146 >>= return . Dir path 157 >>= return . Dir path canonicalPath
147 158
148copyTo :: FilePath -> AnchoredFSNode -> IO () 159copyTo :: FilePath -> AnchoredFSNode -> IO ()
149copyTo target AnchoredFSNode{anchor, root} = copyNode root 160copyTo target AnchoredFSNode{anchor, root} = copyNode root
150 where 161 where
151 copyNode :: FSNode -> IO () 162 copyNode :: FSNode -> IO ()
152 copyNode (File path) = 163 copyNode File{path} =
153 copyFile (localPath $ anchor /> path) (localPath $ target /> path) 164 copyFile (localPath $ anchor /> path) (localPath $ target /> path)
154 165
155 copyNode (Dir path items) = 166 copyNode Dir{path, items} =
156 createDirectoryIfMissing True (localPath $ target /> path) 167 createDirectoryIfMissing True (localPath $ target /> path)
157 >> mapM_ copyNode items 168 >> mapM_ copyNode items
158 169