summaryrefslogtreecommitdiff
path: root/lib/Hakyll/Core/File.hs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Hakyll/Core/File.hs')
-rw-r--r--lib/Hakyll/Core/File.hs93
1 files changed, 93 insertions, 0 deletions
diff --git a/lib/Hakyll/Core/File.hs b/lib/Hakyll/Core/File.hs
new file mode 100644
index 0000000..49af659
--- /dev/null
+++ b/lib/Hakyll/Core/File.hs
@@ -0,0 +1,93 @@
+--------------------------------------------------------------------------------
+-- | Exports simple compilers to just copy files
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Hakyll.Core.File
+ ( CopyFile (..)
+ , copyFileCompiler
+ , TmpFile (..)
+ , newTmpFile
+ ) where
+
+
+--------------------------------------------------------------------------------
+import Data.Binary (Binary (..))
+import Data.Typeable (Typeable)
+#if MIN_VERSION_directory(1,2,6)
+import System.Directory (copyFileWithMetadata)
+#else
+import System.Directory (copyFile)
+#endif
+import System.Directory (doesFileExist,
+ renameFile)
+import System.FilePath ((</>))
+import System.Random (randomIO)
+
+
+--------------------------------------------------------------------------------
+import Hakyll.Core.Compiler
+import Hakyll.Core.Compiler.Internal
+import Hakyll.Core.Configuration
+import Hakyll.Core.Item
+import Hakyll.Core.Provider
+import qualified Hakyll.Core.Store as Store
+import Hakyll.Core.Util.File
+import Hakyll.Core.Writable
+
+
+--------------------------------------------------------------------------------
+-- | This will copy any file directly by using a system call
+newtype CopyFile = CopyFile FilePath
+ deriving (Binary, Eq, Ord, Show, Typeable)
+
+
+--------------------------------------------------------------------------------
+instance Writable CopyFile where
+#if MIN_VERSION_directory(1,2,6)
+ write dst (Item _ (CopyFile src)) = copyFileWithMetadata src dst
+#else
+ write dst (Item _ (CopyFile src)) = copyFile src dst
+#endif
+--------------------------------------------------------------------------------
+copyFileCompiler :: Compiler (Item CopyFile)
+copyFileCompiler = do
+ identifier <- getUnderlying
+ provider <- compilerProvider <$> compilerAsk
+ makeItem $ CopyFile $ resourceFilePath provider identifier
+
+
+--------------------------------------------------------------------------------
+newtype TmpFile = TmpFile FilePath
+ deriving (Typeable)
+
+
+--------------------------------------------------------------------------------
+instance Binary TmpFile where
+ put _ = return ()
+ get = error $
+ "Hakyll.Core.File.TmpFile: You tried to load a TmpFile, however, " ++
+ "this is not possible since these are deleted as soon as possible."
+
+
+--------------------------------------------------------------------------------
+instance Writable TmpFile where
+ write dst (Item _ (TmpFile fp)) = renameFile fp dst
+
+
+--------------------------------------------------------------------------------
+-- | Create a tmp file
+newTmpFile :: String -- ^ Suffix and extension
+ -> Compiler TmpFile -- ^ Resulting tmp path
+newTmpFile suffix = do
+ path <- mkPath
+ compilerUnsafeIO $ makeDirectories path
+ debugCompiler $ "newTmpFile " ++ path
+ return $ TmpFile path
+ where
+ mkPath = do
+ rand <- compilerUnsafeIO $ randomIO :: Compiler Int
+ tmp <- tmpDirectory . compilerConfig <$> compilerAsk
+ let path = tmp </> Store.hash [show rand] ++ "-" ++ suffix
+ exists <- compilerUnsafeIO $ doesFileExist path
+ if exists then mkPath else return path