on master help sign in
Add TmpFile utilities
commitbbc2631c76db01e85ac5c4e75b1babb6c5b05697 authorJasper Van der Jeugt <m@jaspervdj.be> dateSun 6 Jan 2013, 18:33 (14 years ago) parente477ea7
18 files changed+180−108
hakyll.cabal+3−1 src/Hakyll.hs+2−2 src/Hakyll/Commands.hs+3−5 src/Hakyll/Core/Compiler/Internal.hs+4−1 src/Hakyll/Core/Configuration.hs+4 src/Hakyll/Core/File.hs+89 src/Hakyll/Core/Runtime.hs+6−1 src/Hakyll/Core/Store.hs+8−6 src/Hakyll/Core/Util/File.hs+11−2 src/Hakyll/Core/Writable/CopyFile.hs−43 tests/Hakyll/Core/Provider/Tests.hs+2−1 tests/Hakyll/Core/Rules/Tests.hs+3−2 tests/Hakyll/Core/Runtime/Tests.hs+7−4 tests/Hakyll/Core/Store/Tests.hs+4−3 tests/Hakyll/Core/UnixFilter/Tests.hs+3−1 tests/Hakyll/Web/Template/Context/Tests.hs+4−1 tests/Hakyll/Web/Template/Tests.hs+4−2 tests/TestSuite/Util.hs+23−33
hakyll.cabal+3−1
@@ -106,6 +106,7 @@ Library
106106 pandoc >= 1.9.3 && < 1.10,
107107 parsec >= 3.0 && < 3.2,
108108 process >= 1.0 && < 1.2,
109+ random >= 1.0 && < 1.1,
109110 regex-base >= 0.93 && < 0.94,
110111 regex-tdfa >= 1.1 && < 1.2,
111112 tagsoup >= 0.12.6 && < 0.13,
@@ -117,6 +118,7 @@ Library
117118 Hakyll.Core.Compiler
118119 Hakyll.Core.Configuration
119120 Hakyll.Core.Dependencies
121+ Hakyll.Core.File
120122 Hakyll.Core.Identifier
121123 Hakyll.Core.Identifier.Pattern
122124 Hakyll.Core.Item
@@ -125,7 +127,6 @@ Library
125127 Hakyll.Core.Rules
126128 Hakyll.Core.Util.String
127129 Hakyll.Core.Writable
128− Hakyll.Core.Writable.CopyFile
129130 Hakyll.Main
130131 Hakyll.Web.CompressCss
131132 Hakyll.Web.Feed
@@ -211,6 +212,7 @@ Test-suite hakyll-tests
211212 pandoc >= 1.9.3 && < 1.10,
212213 parsec >= 3.0 && < 3.2,
213214 process >= 1.0 && < 1.2,
215+ random >= 1.0 && < 1.1,
214216 regex-base >= 0.93 && < 0.94,
215217 regex-tdfa >= 1.1 && < 1.2,
216218 tagsoup >= 0.12.6 && < 0.13,
src/Hakyll.hs+2−2
@@ -4,6 +4,7 @@
44module Hakyll
55 ( module Hakyll.Core.Compiler
66 , module Hakyll.Core.Configuration
7+ , module Hakyll.Core.File
78 , module Hakyll.Core.Identifier
89 , module Hakyll.Core.Identifier.Pattern
910 , module Hakyll.Core.Item
@@ -16,7 +17,6 @@ module Hakyll
1617 , module Hakyll.Core.Util.File
1718 , module Hakyll.Core.Util.String
1819 , module Hakyll.Core.Writable
19− , module Hakyll.Core.Writable.CopyFile
2020 , module Hakyll.Main
2121 , module Hakyll.Web.CompressCss
2222 , module Hakyll.Web.Feed
@@ -36,6 +36,7 @@ module Hakyll
3636--------------------------------------------------------------------------------
3737import Hakyll.Core.Compiler
3838import Hakyll.Core.Configuration
39+import Hakyll.Core.File
3940import Hakyll.Core.Identifier
4041import Hakyll.Core.Identifier.Pattern
4142import Hakyll.Core.Item
@@ -48,7 +49,6 @@ import Hakyll.Core.UnixFilter
4849import Hakyll.Core.Util.File
4950import Hakyll.Core.Util.String
5051import Hakyll.Core.Writable
51−import Hakyll.Core.Writable.CopyFile
5252import Hakyll.Main
5353import Hakyll.Web.CompressCss
5454import Hakyll.Web.Feed
src/Hakyll/Commands.hs+3−5
@@ -13,9 +13,6 @@ module Hakyll.Commands
1313
1414
1515--------------------------------------------------------------------------------
16−import Control.Monad (when)
17−import System.Directory (doesDirectoryExist,
18− removeDirectoryRecursive)
1916import System.Exit (exitWith)
2017import System.Process (system)
2118
@@ -26,6 +23,7 @@ import Hakyll.Core.Configuration
2623import Hakyll.Core.Logger (Verbosity)
2724import Hakyll.Core.Rules
2825import Hakyll.Core.Runtime
26+import Hakyll.Core.Util.File
2927
3028
3129--------------------------------------------------------------------------------
@@ -59,11 +57,11 @@ clean :: Configuration -> IO ()
5957clean conf = do
6058 remove $ destinationDirectory conf
6159 remove $ storeDirectory conf
60+ remove $ tmpDirectory conf
6261 where
6362 remove dir = do
6463 putStrLn $ "Removing " ++ dir ++ "..."
65− exists <- doesDirectoryExist dir
66− when exists $ removeDirectoryRecursive dir
64+ removeDirectory dir
6765
6866
6967--------------------------------------------------------------------------------
src/Hakyll/Core/Compiler/Internal.hs+4−1
@@ -34,6 +34,7 @@ import qualified Data.Set as S
3434
3535
3636--------------------------------------------------------------------------------
37+import Hakyll.Core.Configuration
3738import Hakyll.Core.Dependencies
3839import Hakyll.Core.Identifier
3940import Hakyll.Core.Identifier.Pattern
@@ -47,7 +48,9 @@ import Hakyll.Core.Store
4748--------------------------------------------------------------------------------
4849-- | Environment in which a compiler runs
4950data CompilerRead = CompilerRead
50− { -- | Underlying identifier
51+ { -- | Main configuration
52+ compilerConfig :: Configuration
53+ , -- | Underlying identifier
5154 compilerUnderlying :: Identifier
5255 , -- | Resource provider
5356 compilerProvider :: Provider
src/Hakyll/Core/Configuration.hs+4
@@ -18,6 +18,8 @@ data Configuration = Configuration
1818 destinationDirectory :: FilePath
1919 , -- | Directory where hakyll's internal store is kept
2020 storeDirectory :: FilePath
21+ , -- | Directory in which some temporary files will be kept
22+ tmpDirectory :: FilePath
2123 , -- | Directory where hakyll finds the files to compile. This is @.@ by
2224 -- default.
2325 providerDirectory :: FilePath
@@ -61,6 +63,7 @@ defaultConfiguration :: Configuration
6163defaultConfiguration = Configuration
6264 { destinationDirectory = "_site"
6365 , storeDirectory = "_cache"
66+ , tmpDirectory = "_cache/tmp"
6467 , providerDirectory = "."
6568 , ignoreFile = ignoreFile'
6669 , deployCommand = "echo 'No deploy command specified'"
@@ -83,6 +86,7 @@ shouldIgnoreFile :: Configuration -> FilePath -> Bool
8386shouldIgnoreFile conf path =
8487 destinationDirectory conf `isPrefixOf` path' ||
8588 storeDirectory conf `isPrefixOf` path' ||
89+ tmpDirectory conf `isPrefixOf` path' ||
8690 ignoreFile conf path'
8791 where
8892 path' = normalise path
src/Hakyll/Core/File.hsnew file+89
@@ -0,0 +1,89 @@
1+--------------------------------------------------------------------------------
2+-- | Exports simple compilers to just copy files
3+{-# LANGUAGE DeriveDataTypeable #-}
4+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5+module Hakyll.Core.File
6+ ( CopyFile (..)
7+ , copyFileCompiler
8+ , TmpFile (..)
9+ , newTmpFile
10+ ) where
11+
12+
13+--------------------------------------------------------------------------------
14+import Control.Applicative ((<$>))
15+import Data.Binary (Binary (..))
16+import Data.Typeable (Typeable)
17+import System.Directory (copyFile, doesFileExist,
18+ renameFile)
19+import System.FilePath ((</>))
20+import System.Random (randomIO)
21+
22+
23+--------------------------------------------------------------------------------
24+import Hakyll.Core.Compiler
25+import Hakyll.Core.Compiler.Internal
26+import Hakyll.Core.Configuration
27+import Hakyll.Core.Identifier
28+import Hakyll.Core.Item
29+import qualified Hakyll.Core.Store as Store
30+import Hakyll.Core.Util.File
31+import Hakyll.Core.Writable
32+
33+
34+--------------------------------------------------------------------------------
35+-- | This will copy any file directly by using a system call
36+data CopyFile = CopyFile
37+ deriving (Show, Eq, Ord, Typeable)
38+
39+
40+--------------------------------------------------------------------------------
41+instance Binary CopyFile where
42+ put CopyFile = return ()
43+ get = return CopyFile
44+
45+
46+--------------------------------------------------------------------------------
47+instance Writable CopyFile where
48+ write dst item = copyFile (toFilePath $ itemIdentifier item) dst
49+
50+
51+--------------------------------------------------------------------------------
52+copyFileCompiler :: Compiler (Item CopyFile)
53+copyFileCompiler = makeItem CopyFile
54+
55+
56+--------------------------------------------------------------------------------
57+newtype TmpFile = TmpFile FilePath
58+ deriving (Typeable)
59+
60+
61+--------------------------------------------------------------------------------
62+instance Binary TmpFile where
63+ put _ = return ()
64+ get = error $
65+ "Hakyll.Core.File.TmpFile: You tried to load a TmpFile, however, " ++
66+ "this is not possible since these are deleted as soon as possible."
67+
68+
69+--------------------------------------------------------------------------------
70+instance Writable TmpFile where
71+ write dst (Item _ (TmpFile fp)) = renameFile fp dst
72+
73+
74+--------------------------------------------------------------------------------
75+-- | Create a tmp file
76+newTmpFile :: String -- ^ Suffix and extension
77+ -> Compiler TmpFile -- ^ Resulting tmp path
78+newTmpFile suffix = do
79+ path <- mkPath
80+ compilerUnsafeIO $ makeDirectories path
81+ debugCompiler $ "newTmpFile " ++ path
82+ return $ TmpFile path
83+ where
84+ mkPath = do
85+ rand <- compilerUnsafeIO $ randomIO :: Compiler Int
86+ tmp <- tmpDirectory . compilerConfig <$> compilerAsk
87+ let path = tmp </> Store.hash [show rand] ++ "-" ++ suffix
88+ exists <- compilerUnsafeIO $ doesFileExist path
89+ if exists then mkPath else return path
src/Hakyll/Core/Runtime.hs+6−1
@@ -85,6 +85,10 @@ run config verbosity rules = do
8585
8686 Right (_, s, _) -> do
8787 Store.set store factsKey $ runtimeFacts s
88+
89+ Logger.debug logger "Removing tmp directory..."
90+ removeDirectory $ tmpDirectory config
91+
8892 Logger.flush logger
8993 return ruleSet
9094 where
@@ -180,7 +184,8 @@ chase trail id'
180184
181185 let compiler = todo M.! id'
182186 read' = CompilerRead
183− { compilerUnderlying = id'
187+ { compilerConfig = config
188+ , compilerUnderlying = id'
184189 , compilerProvider = provider
185190 , compilerUniverse = M.keysSet universe
186191 , compilerRoutes = routes
src/Hakyll/Core/Store.hs+8−6
@@ -9,6 +9,7 @@ module Hakyll.Core.Store
99 , set
1010 , get
1111 , delete
12+ , hash
1213 ) where
1314
1415
@@ -143,13 +144,14 @@ delete store identifier = do
143144 key = hash identifier
144145
145146
146−--------------------------------------------------------------------------------
147−hash :: [String] -> String
148−hash = concatMap (printf "%02x") . B.unpack .
149− MD5.hash . T.encodeUtf8 . T.pack . intercalate "/"
150−
151−
152147--------------------------------------------------------------------------------
153148-- | Delete a file unless it doesn't exist...
154149deleteFile :: FilePath -> IO ()
155150deleteFile = handle (\(_ :: IOException) -> return ()) . removeFile
151+
152+
153+--------------------------------------------------------------------------------
154+-- | Mostly meant for internal usage
155+hash :: [String] -> String
156+hash = concatMap (printf "%02x") . B.unpack .
157+ MD5.hash . T.encodeUtf8 . T.pack . intercalate "/"
src/Hakyll/Core/Util/File.hs+11−2
@@ -3,14 +3,16 @@
33module Hakyll.Core.Util.File
44 ( makeDirectories
55 , getRecursiveContents
6+ , removeDirectory
67 ) where
78
89
910--------------------------------------------------------------------------------
1011import Control.Applicative ((<$>))
11−import Control.Monad (forM)
12+import Control.Monad (forM, when)
1213import System.Directory (createDirectoryIfMissing,
13− doesDirectoryExist, getDirectoryContents)
14+ doesDirectoryExist, getDirectoryContents,
15+ removeDirectoryRecursive)
1416import System.FilePath (takeDirectory, (</>))
1517
1618
@@ -42,3 +44,10 @@ getRecursiveContents top = go ""
4244 else return [rel]
4345
4446 return $ concat paths
47+
48+
49+--------------------------------------------------------------------------------
50+removeDirectory :: FilePath -> IO ()
51+removeDirectory fp = do
52+ e <- doesDirectoryExist fp
53+ when e $ removeDirectoryRecursive fp
src/Hakyll/Core/Writable/CopyFile.hsdeleted−43
@@ -1,43 +0,0 @@
1−--------------------------------------------------------------------------------
2−-- | Exports simple compilers to just copy files
3−{-# LANGUAGE DeriveDataTypeable #-}
4−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5−module Hakyll.Core.Writable.CopyFile
6− ( CopyFile (..)
7− , copyFileCompiler
8− ) where
9−
10−
11−--------------------------------------------------------------------------------
12−import Data.Binary (Binary (..))
13−import Data.Typeable (Typeable)
14−import System.Directory (copyFile)
15−
16−
17−--------------------------------------------------------------------------------
18−import Hakyll.Core.Compiler
19−import Hakyll.Core.Identifier
20−import Hakyll.Core.Item
21−import Hakyll.Core.Writable
22−
23−
24−--------------------------------------------------------------------------------
25−-- | This will copy any file directly by using a system call
26−data CopyFile = CopyFile
27− deriving (Show, Eq, Ord, Typeable)
28−
29−
30−--------------------------------------------------------------------------------
31−instance Binary CopyFile where
32− put CopyFile = return ()
33− get = return CopyFile
34−
35−
36−--------------------------------------------------------------------------------
37−instance Writable CopyFile where
38− write dst item = copyFile (toFilePath $ itemIdentifier item) dst
39−
40−
41−--------------------------------------------------------------------------------
42−copyFileCompiler :: Compiler (Item CopyFile)
43−copyFileCompiler = makeItem CopyFile
tests/Hakyll/Core/Provider/Tests.hs+2−1
@@ -26,7 +26,8 @@ tests = testGroup "Hakyll.Core.Provider.Tests"
2626
2727--------------------------------------------------------------------------------
2828case01 :: Assertion
29−case01 = withTestStore $ \store -> do
29+case01 = do
30+ store <- newTestStore
3031 provider <- newTestProvider store
3132 assert $ resourceExists provider "example.md"
3233
tests/Hakyll/Core/Rules/Tests.hs+3−2
@@ -14,12 +14,12 @@ import Test.HUnit (Assertion, assert, (@=?))
1414
1515--------------------------------------------------------------------------------
1616import Hakyll.Core.Compiler
17+import Hakyll.Core.File
1718import Hakyll.Core.Identifier
1819import Hakyll.Core.Identifier.Pattern
1920import Hakyll.Core.Routes
2021import Hakyll.Core.Rules
2122import Hakyll.Core.Rules.Internal
22−import Hakyll.Core.Writable.CopyFile
2323import Hakyll.Web.Pandoc
2424import TestSuite.Util
2525
@@ -33,7 +33,8 @@ tests = testGroup "Hakyll.Core.Rules.Tests"
3333
3434--------------------------------------------------------------------------------
3535rulesTest :: Assertion
36−rulesTest = withTestStore $ \store -> do
36+rulesTest = do
37+ store <- newTestStore
3738 provider <- newTestProvider store
3839 ruleSet <- runRules rules provider
3940 let identifiers = S.fromList $ map fst $ rulesCompilers ruleSet
tests/Hakyll/Core/Runtime/Tests.hs+7−4
@@ -25,8 +25,8 @@ tests = testGroup "Hakyll.Core.Runtime.Tests" $ fromAssertions "run" [case01]
2525
2626--------------------------------------------------------------------------------
2727case01 :: Assertion
28−case01 = withTestConfiguration $ \config -> do
29− _ <- run config Logger.Error $ do
28+case01 = do
29+ _ <- run testConfiguration Logger.Error $ do
3030 match "*.md" $ do
3131 route $ setExtension "html"
3232 compile $ do
@@ -40,8 +40,11 @@ case01 = withTestConfiguration $ \config -> do
4040 items <- loadAllSnapshots "*.md" "raw"
4141 makeItem $ concat $ map itemBody (items :: [Item String])
4242
43− example <- readFile $ destinationDirectory config </> "example.html"
43+ example <- readFile $
44+ destinationDirectory testConfiguration </> "example.html"
4445 lines example @?= ["<p>This is an example.</p>"]
4546
46− bodies <- readFile $ destinationDirectory config </> "bodies.txt"
47+ bodies <- readFile $ destinationDirectory testConfiguration </> "bodies.txt"
4748 head (lines bodies) @?= "This is an example."
49+
50+ cleanTestEnv
tests/Hakyll/Core/Store/Tests.hs+4−3
@@ -38,7 +38,7 @@ simpleSetGet = Q.monadicIO $ do
3838 Q.run $ Store.set store key (value :: String)
3939 value' <- Q.run $ Store.get store key
4040 Q.assert $ Store.Found value == value'
41− Q.run cleanTestStore
41+ Q.run cleanTestEnv
4242
4343
4444--------------------------------------------------------------------------------
@@ -52,12 +52,13 @@ persistentSetGet = Q.monadicIO $ do
5252 store2 <- Q.run newTestStore
5353 value' <- Q.run $ Store.get store2 key
5454 Q.assert $ Store.Found value == value'
55− Q.run cleanTestStore
55+ Q.run cleanTestEnv
5656
5757
5858--------------------------------------------------------------------------------
5959wrongType :: H.Assertion
60−wrongType = withTestStore $ \store -> do
60+wrongType = do
61+ store <- newTestStore
6162 -- Store a string and try to fetch an int
6263 Store.set store ["foo", "bar"] ("qux" :: String)
6364 value <- Store.get store ["foo", "bar"] :: IO (Store.Result Int)
tests/Hakyll/Core/UnixFilter/Tests.hs+3−1
@@ -27,11 +27,13 @@ tests = testGroup "Hakyll.Core.UnixFilter.Tests"
2727
2828--------------------------------------------------------------------------------
2929unixFilterRev :: H.Assertion
30−unixFilterRev = withTestStore $ \store -> do
30+unixFilterRev = do
31+ store <- newTestStore
3132 provider <- newTestProvider store
3233 output <- testCompilerDone store provider "russian.md" compiler
3334 expected <- testCompilerDone store provider "russian.md" getResourceString
3435 H.assert $ rev (itemBody expected) == lines (itemBody output)
36+ cleanTestEnv
3537 where
3638 compiler = getResourceString >>= withItemBody (unixFilter "rev" [])
3739 rev = map reverse . lines
tests/Hakyll/Web/Template/Context/Tests.hs+4−1
@@ -29,7 +29,8 @@ tests = testGroup "Hakyll.Core.Template.Context.Tests"
2929
3030--------------------------------------------------------------------------------
3131testDateField :: Assertion
32−testDateField = withTestStore $ \store -> do
32+testDateField = do
33+ store <- newTestStore
3334 provider <- newTestProvider store
3435
3536 date1 <- testContextDone store provider "example.md" "date" $
@@ -41,6 +42,8 @@ testDateField = withTestStore $ \store -> do
4142 dateField "date" "%B %e, %Y"
4243 date2 @=? "August 26, 2010"
4344
45+ cleanTestEnv
46+
4447
4548--------------------------------------------------------------------------------
4649testContextDone :: Store -> Provider -> Identifier -> String
tests/Hakyll/Web/Template/Tests.hs+4−2
@@ -30,11 +30,13 @@ tests = testGroup "Hakyll.Core.Template.Tests"
3030
3131--------------------------------------------------------------------------------
3232case01 :: Assertion
33−case01 = withTestStore $ \store -> do
33+case01 = do
34+ store <- newTestStore
3435 provider <- newTestProvider store
3536
3637 out <- resourceString provider "template.html.out"
37− tpl <- testCompilerDone store provider "template.html" $ templateCompiler
38+ tpl <- testCompilerDone store provider "template.html" $
39+ templateCompiler
3840 item <- testCompilerDone store provider "example.md" $
3941 pandocCompiler >>= applyTemplate (itemBody tpl) testContext
4042
tests/TestSuite/Util.hs+23−33
@@ -3,19 +3,17 @@
33module TestSuite.Util
44 ( fromAssertions
55 , newTestStore
6− , cleanTestStore
7− , withTestStore
86 , newTestProvider
97 , testCompiler
108 , testCompilerDone
11− , withTestConfiguration
9+ , testConfiguration
10+ , cleanTestEnv
1211 ) where
1312
1413
1514--------------------------------------------------------------------------------
1615import Data.Monoid (mempty)
1716import qualified Data.Set as S
18−import System.Directory (removeDirectoryRecursive)
1917import Test.Framework
2018import Test.Framework.Providers.HUnit
2119import Test.HUnit hiding (Test)
@@ -30,6 +28,7 @@ import qualified Hakyll.Core.Logger as Logger
3028import Hakyll.Core.Provider
3129import Hakyll.Core.Store (Store)
3230import qualified Hakyll.Core.Store as Store
31+import Hakyll.Core.Util.File
3332
3433
3534--------------------------------------------------------------------------------
@@ -42,26 +41,13 @@ fromAssertions name =
4241
4342--------------------------------------------------------------------------------
4443newTestStore :: IO Store
45−newTestStore = Store.new True "_teststore"
46−
47−
48−--------------------------------------------------------------------------------
49−cleanTestStore :: IO ()
50−cleanTestStore = removeDirectoryRecursive "_teststore"
51−
52−
53−--------------------------------------------------------------------------------
54−withTestStore :: (Store -> IO a) -> IO a
55−withTestStore f = do
56− store <- newTestStore
57− result <- f store
58− cleanTestStore
59− return result
44+newTestStore = Store.new True $ storeDirectory testConfiguration
6045
6146
6247--------------------------------------------------------------------------------
6348newTestProvider :: Store -> IO Provider
64−newTestProvider store = newProvider store (const False) "tests/data"
49+newTestProvider store = newProvider store (const False) $
50+ providerDirectory testConfiguration
6551
6652
6753--------------------------------------------------------------------------------
@@ -70,7 +56,8 @@ testCompiler :: Store -> Provider -> Identifier -> Compiler a
7056testCompiler store provider underlying compiler = do
7157 logger <- Logger.new Logger.Error
7258 let read' = CompilerRead
73− { compilerUnderlying = underlying
59+ { compilerConfig = testConfiguration
60+ , compilerUnderlying = underlying
7461 , compilerProvider = provider
7562 , compilerUniverse = S.empty
7663 , compilerRoutes = mempty
@@ -99,15 +86,18 @@ testCompilerDone store provider underlying compiler = do
9986
10087
10188--------------------------------------------------------------------------------
102−withTestConfiguration :: (Configuration -> IO a) -> IO a
103−withTestConfiguration f = do
104− x <- f config
105− removeDirectoryRecursive $ destinationDirectory config
106− removeDirectoryRecursive $ storeDirectory config
107− return x
108− where
109− config = defaultConfiguration
110− { destinationDirectory = "_testsite"
111− , storeDirectory = "_teststore"
112− , providerDirectory = "tests/data"
113− }
89+testConfiguration :: Configuration
90+testConfiguration = defaultConfiguration
91+ { destinationDirectory = "_testsite"
92+ , storeDirectory = "_teststore"
93+ , tmpDirectory = "_testtmp"
94+ , providerDirectory = "tests/data"
95+ }
96+
97+
98+--------------------------------------------------------------------------------
99+cleanTestEnv :: IO ()
100+cleanTestEnv = do
101+ removeDirectory $ destinationDirectory testConfiguration
102+ removeDirectory $ storeDirectory testConfiguration
103+ removeDirectory $ tmpDirectory testConfiguration