-------------------------------------------------------------------------------- -- | 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