cautious-file 0.1.1 → 0.1.2
raw patch · 3 files changed
+72/−6 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- System/IO/Cautious.hs +6/−5
- Test.hs +64/−0
- cautious-file.cabal +2/−1
System/IO/Cautious.hs view
@@ -11,11 +11,11 @@ import Prelude hiding (writeFile) -import System.Directory (renameFile)+import System.Directory (canonicalizePath, renameFile) import System.FilePath (splitFileName) import System.IO (openTempFile) #ifdef _POSIX-import Control.Monad (when)+import Control.Monad (unless) import Data.Function (fix) import Data.List (genericDrop) import System.Posix.IO (closeFd, FdOption (SynchronousWrites), fdWrite, handleToFd, setFdOption)@@ -27,7 +27,7 @@ -- | Write the entire contents of a string to a file descriptor. Assumes blocking mode. writeAll :: Fd -> String -> IO ()-writeAll fd = fix $ \me s -> when (not $ null s) $ do+writeAll fd = fix $ \me s -> unless (null s) $ do count <- fdWrite fd s me $ genericDrop count s #else@@ -41,7 +41,8 @@ -- old version of the file. writeFileWithBackup :: IO () -> FilePath -> String -> IO () writeFileWithBackup backup fp text = do- (tempFP, handle) <- uncurry openTempFile $ splitFileName fp+ cfp <- canonicalizePath fp+ (tempFP, handle) <- uncurry openTempFile $ splitFileName cfp #ifdef _POSIX fd <- handleToFd handle let writeSync = (setFdOption fd SynchronousWrites True >>) . writeAll fd@@ -54,4 +55,4 @@ hClose handle #endif backup- renameFile tempFP fp+ renameFile tempFP cfp
+ Test.hs view
@@ -0,0 +1,64 @@+{-# LANGUAGE CPP #-}+module Main where++import System.IO.Cautious (writeFile)++import Prelude hiding (writeFile)+import Control.Monad (replicateM, zipWithM_, unless)+import System.Directory (removeFile)+import System.Environment (getArgs)+#ifdef _POSIX+import System.Posix.Files (createSymbolicLink, readSymbolicLink)+#endif+import System.Random (mkStdGen, randomRIO, setStdGen)++-- Remember that because we are using zipWithM_ below, the lengths of testLengths and outputFilePaths need to be the same!+testLengths :: [Int]+testLengths = [ 0 -- Extreme value+ , 1 -- Extreme value+ , 65530 -- Normal value below split limit+ , 65536 -- Split limit+ , 128000 -- Normal value above split limit+ ]++outputFilePaths :: [FilePath]+outputFilePaths = ["foo", "foo.txt", "./bar.txt", ".dotfile", "./.dot.dot"]++defaultSeed :: Int+defaultSeed = 1234++stdTestCase :: Int -> FilePath -> IO ()+stdTestCase dataLen outputFile = do+ testData <- replicateM dataLen $ randomRIO ('\0', '\255')+ writeFile outputFile testData+ testData' <- readFile outputFile+ unless (testData == testData') . fail $ "stdTestCase: failed with " ++ show dataLen ++ " " ++ show outputFile+ removeFile outputFile++#ifdef _POSIX+symlinkTestCase :: IO ()+symlinkTestCase = do+ let linkTarget = "link-dest"+ linkSrc = "link"+ testData = "hi"+ writeFile linkTarget ""+ createSymbolicLink linkTarget linkSrc+ writeFile linkSrc testData+ newTarget <- readSymbolicLink linkSrc+ testData' <- readFile linkTarget+ unless (testData == testData') $ fail "symlinkTestCase failed: data read back not the same as data written out!"+ unless (newTarget == linkTarget) $ fail "symlinkTestCase failed: symlink clobbered"+ mapM_ removeFile [linkSrc, linkTarget]+#endif++main :: IO ()+main = do+ args <- getArgs+ setStdGen . mkStdGen $ if null args then defaultSeed else read (head args)+ zipWithM_ stdTestCase testLengths outputFilePaths+#ifdef _POSIX+ symlinkTestCase+#else+ putStrLn "Warning: POSIX tests not run! If you are on a POSIX platform, then to run them type 'runhaskell -D_POSIX Test.hs'"+#endif+ putStrLn "All cautious-file tests completed successfully!"
cautious-file.cabal view
@@ -1,5 +1,5 @@ name: cautious-file-version: 0.1.1+version: 0.1.2 Cabal-Version: >= 1.6 synopsis: Ways to write a file cautiously, to reduce the chances of problems such as data loss due to crashes or power failures description: If the posix flag is enabled, posix-specific functions are used to reduce the chance of data loss further@@ -13,6 +13,7 @@ stability: experimental bug-reports: mailto:greenrd@greenrd.org tested-with: GHC == 6.10.3+extra-source-files: Test.hs source-repository head type: darcs