git-annex/Utility/TempFile.hs

72 lines
2.4 KiB
Haskell
Raw Normal View History

2011-10-16 04:31:25 +00:00
{- temp file functions
-
2013-05-12 20:38:00 +00:00
- Copyright 2010-2013 Joey Hess <joey@kitenet.net>
2011-10-16 04:31:25 +00:00
-
- Licensed under the GNU GPL version 3 or higher.
-}
module Utility.TempFile where
import Control.Exception (bracket)
2011-10-16 04:31:25 +00:00
import System.IO
import System.Directory
2013-05-12 20:38:00 +00:00
import Control.Monad.IfElse
2011-10-16 04:31:25 +00:00
import Utility.Exception
2012-09-10 18:09:13 +00:00
import System.FilePath
2011-10-16 04:31:25 +00:00
2013-05-12 20:38:00 +00:00
type Template = String
2011-10-16 04:31:25 +00:00
{- Runs an action like writeFile, writing to a temp file first and
- then moving it into place. The temp file is stored in the same
- directory as the final file to avoid cross-device renames. -}
viaTmp :: (FilePath -> String -> IO ()) -> FilePath -> String -> IO ()
viaTmp a file content = do
2013-05-12 20:38:00 +00:00
let (dir, base) = splitFileName file
createDirectoryIfMissing True dir
(tmpfile, handle) <- openTempFile dir (base ++ ".tmp")
hClose handle
2011-10-16 04:31:25 +00:00
a tmpfile content
renameFile tmpfile file
2012-01-21 06:24:12 +00:00
2013-05-12 20:38:00 +00:00
{- Runs an action with a tmp file located in the system's tmp directory
- (or in "." if there is none) then removes the file. -}
2012-01-21 06:24:12 +00:00
withTempFile :: Template -> (FilePath -> Handle -> IO a) -> IO a
2013-05-12 20:38:00 +00:00
withTempFile template a = do
tmpdir <- catchDefaultIO "." getTemporaryDirectory
withTempFileIn tmpdir template a
{- Runs an action with a tmp file located in the specified directory,
- then removes the file. -}
withTempFileIn :: FilePath -> Template -> (FilePath -> Handle -> IO a) -> IO a
withTempFileIn tmpdir template a = bracket create remove use
2012-11-12 21:43:10 +00:00
where
2013-05-12 20:38:00 +00:00
create = openTempFile tmpdir template
2012-11-12 21:43:10 +00:00
remove (name, handle) = do
hClose handle
catchBoolIO (removeFile name >> return True)
use (name, handle) = a name handle
2012-09-10 18:09:13 +00:00
2013-05-12 20:38:00 +00:00
{- Runs an action with a tmp directory located within the system's tmp
- directory (or within "." if there is none), then removes the tmp
- directory and all its contents. -}
2012-09-10 18:09:13 +00:00
withTempDir :: Template -> (FilePath -> IO a) -> IO a
2013-05-12 20:38:00 +00:00
withTempDir template a = do
tmpdir <- catchDefaultIO "." getTemporaryDirectory
withTempDirIn tmpdir template a
{- Runs an action with a tmp directory located within a specified directory,
- then removes the tmp directory and all its contents. -}
withTempDirIn :: FilePath -> Template -> (FilePath -> IO a) -> IO a
withTempDirIn tmpdir template = bracket create remove
2012-11-12 21:43:10 +00:00
where
2013-05-12 20:38:00 +00:00
remove d = whenM (doesDirectoryExist d) $
removeDirectoryRecursive d
2012-11-12 21:43:10 +00:00
create = do
createDirectoryIfMissing True tmpdir
2013-05-12 20:38:00 +00:00
makenewdir (tmpdir </> template) (0 :: Int)
makenewdir t n = do
let dir = t ++ "." ++ show n
either (const $ makenewdir t $ n + 1) (const $ return dir)
=<< tryIO (createDirectory dir)