atomic-write-0.2.0.7/spec/0000755000000000000000000000000013565556026013417 5ustar0000000000000000atomic-write-0.2.0.7/spec/System/0000755000000000000000000000000013565556026014703 5ustar0000000000000000atomic-write-0.2.0.7/spec/System/AtomicWrite/0000755000000000000000000000000013565556026017132 5ustar0000000000000000atomic-write-0.2.0.7/spec/System/AtomicWrite/Writer/0000755000000000000000000000000013565556026020406 5ustar0000000000000000atomic-write-0.2.0.7/spec/System/AtomicWrite/Writer/ByteString/0000755000000000000000000000000013565556026022500 5ustar0000000000000000atomic-write-0.2.0.7/spec/System/AtomicWrite/Writer/LazyByteString/0000755000000000000000000000000013565556026023340 5ustar0000000000000000atomic-write-0.2.0.7/spec/System/AtomicWrite/Writer/LazyText/0000755000000000000000000000000013565556026022172 5ustar0000000000000000atomic-write-0.2.0.7/spec/System/AtomicWrite/Writer/String/0000755000000000000000000000000013565556026021654 5ustar0000000000000000atomic-write-0.2.0.7/spec/System/AtomicWrite/Writer/Text/0000755000000000000000000000000013565556026021332 5ustar0000000000000000atomic-write-0.2.0.7/src/0000755000000000000000000000000013565556026013254 5ustar0000000000000000atomic-write-0.2.0.7/src/System/0000755000000000000000000000000013565556026014540 5ustar0000000000000000atomic-write-0.2.0.7/src/System/AtomicWrite/0000755000000000000000000000000013565556026016767 5ustar0000000000000000atomic-write-0.2.0.7/src/System/AtomicWrite/Writer/0000755000000000000000000000000013565556026020243 5ustar0000000000000000atomic-write-0.2.0.7/src/System/AtomicWrite/Writer/ByteString/0000755000000000000000000000000013565556026022335 5ustar0000000000000000atomic-write-0.2.0.7/src/System/AtomicWrite/Writer/LazyByteString/0000755000000000000000000000000013565556026023175 5ustar0000000000000000atomic-write-0.2.0.7/src/System/AtomicWrite/Writer/LazyText/0000755000000000000000000000000013565556026022027 5ustar0000000000000000atomic-write-0.2.0.7/src/System/AtomicWrite/Writer/String/0000755000000000000000000000000013565556026021511 5ustar0000000000000000atomic-write-0.2.0.7/src/System/AtomicWrite/Writer/Text/0000755000000000000000000000000013565556026021167 5ustar0000000000000000atomic-write-0.2.0.7/src/System/AtomicWrite/Writer/ByteString.hs0000644000000000000000000000306113565556026022671 0ustar0000000000000000-- | -- Module : System.AtomicWrite.Writer.ByteString -- Copyright : © 2015-2019 Stack Builders Inc. -- License : MIT -- -- Maintainer : Stack Builders -- Stability : experimental -- Portability : portable -- -- Provides functionality to dump the contents of a ByteString -- to a file in text mode. module System.AtomicWrite.Writer.ByteString (atomicWriteFile, atomicWriteFileWithMode) where import System.AtomicWrite.Internal (atomicWriteFileMaybeModeText) import System.Posix.Types (FileMode) import Data.ByteString (ByteString, hPutStr) -- | Creates or modifies a file atomically on POSIX-compliant -- systems while preserving permissions. atomicWriteFile :: FilePath -- ^ The path where the file will be updated or created -> ByteString -- ^ The content to write to the file -> IO () atomicWriteFile = atomicWriteFileMaybeMode Nothing -- | Creates or modifies a file atomically on POSIX-compliant -- systems and updates permissions. atomicWriteFileWithMode :: FileMode -> FilePath -- ^ The path where the file will be updated or created -> ByteString -- ^ The content to write to the file -> IO () atomicWriteFileWithMode = atomicWriteFileMaybeMode . Just -- | Helper function atomicWriteFileMaybeMode :: Maybe FileMode -> FilePath -- ^ The path where the file will be updated or created -> ByteString -- ^ The content to write to the file -> IO () atomicWriteFileMaybeMode mmode path = atomicWriteFileMaybeModeText mmode path hPutStr atomic-write-0.2.0.7/src/System/AtomicWrite/Writer/ByteString/Binary.hs0000644000000000000000000000330513565556026024116 0ustar0000000000000000-- | -- Module : System.AtomicWrite.Writer.ByteString.Binary -- Copyright : © 2015-2019 Stack Builders Inc. -- License : MIT -- -- Maintainer : Stack Builders -- Stability : experimental -- Portability : portable -- -- Provides functionality to dump the contents of a ByteString -- to a file open in binary mode module System.AtomicWrite.Writer.ByteString.Binary (atomicWriteFile, atomicWriteFileWithMode) where import System.AtomicWrite.Internal (atomicWriteFileMaybeModeBinary) import System.Posix.Types (FileMode) import Data.ByteString (ByteString, hPutStr) -- | Creates or modifies a file atomically on POSIX-compliant -- systems while preserving permissions. The file is opened in -- binary mode. atomicWriteFile :: FilePath -- ^ The path where the file will be updated or created -> ByteString -- ^ The content to write to the file -> IO () atomicWriteFile = atomicWriteFileMaybeMode Nothing -- | Creates or modifies a file atomically on POSIX-compliant -- systems and updates permissions. The file is opened in binary -- mode. atomicWriteFileWithMode :: FileMode -> FilePath -- ^ The path where the file will be updated or created -> ByteString -- ^ The content to write to the file -> IO () atomicWriteFileWithMode mode = atomicWriteFileMaybeMode $ Just mode -- | Helper function for opening the file in binary mode. atomicWriteFileMaybeMode :: Maybe FileMode -> FilePath -- ^ The path where the file will be updated or created -> ByteString -- ^ The content to write to the file -> IO () atomicWriteFileMaybeMode mmode path = atomicWriteFileMaybeModeBinary mmode path hPutStr atomic-write-0.2.0.7/src/System/AtomicWrite/Writer/ByteStringBuilder.hs0000644000000000000000000000425313565556026024204 0ustar0000000000000000-- | -- Module : System.AtomicWrite.Writer.ByteStringBuilder -- Copyright : © 2015-2019 Stack Builders Inc. -- License : MIT -- -- Maintainer : Stack Builders -- Stability : experimental -- Portability : portable -- -- Provides functionality to dump the contents of a ByteStringBuilder -- to a file. module System.AtomicWrite.Writer.ByteStringBuilder (atomicWriteFile, atomicWriteFileWithMode) where import System.AtomicWrite.Internal (closeAndRename, maybeSetFileMode, tempFileFor) import Data.ByteString.Builder (Builder, hPutBuilder) import GHC.IO.Handle (BufferMode (BlockBuffering), hSetBinaryMode, hSetBuffering) import System.Posix.Types (FileMode) -- | Creates or modifies a file atomically on POSIX-compliant -- systems while preserving permissions. atomicWriteFile :: FilePath -- ^ The path where the file will be updated or created -> Builder -- ^ The content to write to the file -> IO () atomicWriteFile = atomicWriteFileMaybeMode Nothing -- | Creates or modifies a file atomically on POSIX-compliant -- systems and updates permissions. atomicWriteFileWithMode :: FileMode -> FilePath -- ^ The path where the file will be updated or created -> Builder -- ^ The content to write to the file -> IO () atomicWriteFileWithMode mode = atomicWriteFileMaybeMode $ Just mode -- Helper function atomicWriteFileMaybeMode :: Maybe FileMode -> FilePath -- ^ The path where the file will be updated or created -> Builder -- ^ The content to write to the file -> IO () atomicWriteFileMaybeMode mmode path builder = do (temppath, h) <- tempFileFor path -- Recommendations for binary and buffering are from the -- Data.ByteString.Builder docs: -- http://hackage.haskell.org/package/bytestring-0.10.2.0/docs/Data-ByteString-Builder.html#v:hPutBuilder hSetBinaryMode h True hSetBuffering h (BlockBuffering Nothing) hPutBuilder h builder closeAndRename h temppath path -- set new permissions if a FileMode was provided maybeSetFileMode path mmode atomic-write-0.2.0.7/src/System/AtomicWrite/Writer/LazyByteString.hs0000644000000000000000000000316313565556026023534 0ustar0000000000000000-- | -- Module : System.AtomicWrite.Writer.LazyByteString -- Copyright : © 2015-2019 Stack Builders Inc. -- License : MIT -- -- Maintainer : Stack Builders -- Stability : experimental -- Portability : portable -- -- Provides functionality to dump the contents of a Lazy ByteString -- to a file. module System.AtomicWrite.Writer.LazyByteString (atomicWriteFile, atomicWriteFileWithMode) where import System.AtomicWrite.Internal (atomicWriteFileMaybeModeText) import Data.ByteString.Lazy (ByteString, hPutStr) import System.Posix.Types (FileMode) -- | Creates or modifies a file atomically on POSIX-compliant -- systems while preserving permissions. atomicWriteFile :: FilePath -- ^ The path where the file will be updated or created -> ByteString -- ^ The content to write to the file -> IO () atomicWriteFile = atomicWriteFileMaybeMode Nothing -- | Creates or modifies a file atomically on -- POSIX-compliant systems and updates permissions atomicWriteFileWithMode :: FileMode -- ^ The mode to set the file to -> FilePath -- ^ The path where the file will be updated or created -> ByteString -- ^ The content to write to the file -> IO () atomicWriteFileWithMode = atomicWriteFileMaybeMode . Just -- Helper Function atomicWriteFileMaybeMode :: Maybe FileMode -- ^ The mode to set the file to -> FilePath -- ^ The path where the file will be updated or created -> ByteString -- ^ The content to write to the file -> IO () atomicWriteFileMaybeMode mmode path = atomicWriteFileMaybeModeText mmode path hPutStr atomic-write-0.2.0.7/src/System/AtomicWrite/Writer/LazyByteString/Binary.hs0000644000000000000000000000322313565556026024755 0ustar0000000000000000-- | -- Module : System.AtomicWrite.Writer.LazyByteString.Binary -- Copyright : © 2015-2019 Stack Builders Inc. -- License : MIT -- -- Maintainer : Stack Builders -- Stability : experimental -- Portability : portable -- -- Provides functionality to dump the contents of a Lazy ByteString -- to a file in binary mode. module System.AtomicWrite.Writer.LazyByteString.Binary (atomicWriteFile, atomicWriteFileWithMode) where import System.AtomicWrite.Internal (atomicWriteFileMaybeModeBinary) import Data.ByteString.Lazy (ByteString, hPutStr) import System.Posix.Types (FileMode) -- | Creates or modifies a file atomically on POSIX-compliant -- systems while preserving permissions. atomicWriteFile :: FilePath -- ^ The path where the file will be updated or created -> ByteString -- ^ The content to write to the file -> IO () atomicWriteFile = atomicWriteFileMaybeMode Nothing -- | Creates or modifies a file atomically on -- POSIX-compliant systems and updates permissions atomicWriteFileWithMode :: FileMode -- ^ The mode to set the file to -> FilePath -- ^ The path where the file will be updated or created -> ByteString -- ^ The content to write to the file -> IO () atomicWriteFileWithMode = atomicWriteFileMaybeMode . Just -- Helper Function atomicWriteFileMaybeMode :: Maybe FileMode -- ^ The mode to set the file to -> FilePath -- ^ The path where the file will be updated or created -> ByteString -- ^ The content to write to the file -> IO () atomicWriteFileMaybeMode mmode path = atomicWriteFileMaybeModeBinary mmode path hPutStr atomic-write-0.2.0.7/src/System/AtomicWrite/Writer/String.hs0000644000000000000000000000427213565556026022052 0ustar0000000000000000-- | -- Module : System.AtomicWrite.Writer.String -- Copyright : © 2015-2019 Stack Builders Inc. -- License : MIT -- -- Maintainer : Stack Builders -- Stability : experimental -- Portability : portable -- -- Provides functionality to dump the contents of a String -- to a file. module System.AtomicWrite.Writer.String (atomicWriteFile, atomicWithFile, atomicWriteFileWithMode, atomicWithFileAndMode) where import System.AtomicWrite.Internal (closeAndRename, maybeSetFileMode, tempFileFor) import System.IO (Handle, hPutStr) import System.Posix.Types (FileMode) -- | Creates or modifies a file atomically on POSIX-compliant -- systems while preserving permissions. atomicWriteFile :: FilePath -- ^ The path where the file will be updated or created -> String -- ^ The content to write to the file -> IO () atomicWriteFile = (. flip hPutStr) . atomicWithFile -- | Creates or modifies a file atomically on -- POSIX-compliant systems and updates permissions atomicWriteFileWithMode :: FileMode -- ^ The mode to set the file to -> FilePath -- ^ The path where the file will be updated or created -> String -- ^ The content to write to the file -> IO () atomicWriteFileWithMode mode = ( . flip hPutStr) . atomicWithFileAndMode mode -- | A general version of 'atomicWriteFile' atomicWithFile :: FilePath -> (Handle -> IO ()) -> IO () atomicWithFile = atomicWithFileAndMaybeMode Nothing -- | A general version of 'atomicWriteFileWithMode' atomicWithFileAndMode :: FileMode -> FilePath -> (Handle -> IO ()) -> IO () atomicWithFileAndMode = atomicWithFileAndMaybeMode . Just -- | Helper function atomicWithFileAndMaybeMode :: Maybe FileMode -> FilePath -> (Handle -> IO ()) -> IO () atomicWithFileAndMaybeMode mmode path action = tempFileFor path >>= \(tmpPath, h) -> action h >> closeAndRename h tmpPath path >> maybeSetFileMode path mmode atomic-write-0.2.0.7/src/System/AtomicWrite/Writer/String/Binary.hs0000644000000000000000000000442413565556026023275 0ustar0000000000000000-- | -- Module : System.AtomicWrite.Writer.String.Binary -- Copyright : © 2015-2019 Stack Builders Inc. -- License : MIT -- -- Maintainer : Stack Builders -- Stability : experimental -- Portability : portable -- -- Provides functionality to dump the contents of a String -- to a file in binary mode. module System.AtomicWrite.Writer.String.Binary (atomicWriteFile, atomicWithFile, atomicWriteFileWithMode, atomicWithFileAndMode) where import System.AtomicWrite.Internal (closeAndRename, maybeSetFileMode, tempFileFor) import System.IO (Handle, hPutStr, hSetBinaryMode) import System.Posix.Types (FileMode) -- | Creates or modifies a file atomically on POSIX-compliant -- systems while preserving permissions. atomicWriteFile :: FilePath -- ^ The path where the file will be updated or created -> String -- ^ The content to write to the file -> IO () atomicWriteFile = (. flip hPutStr) . atomicWithFile -- | Creates or modifies a file atomically on -- POSIX-compliant systems and updates permissions atomicWriteFileWithMode :: FileMode -- ^ The mode to set the file to -> FilePath -- ^ The path where the file will be updated or created -> String -- ^ The content to write to the file -> IO () atomicWriteFileWithMode mode = ( . flip hPutStr) . atomicWithFileAndMode mode -- | A general version of 'atomicWriteFile' atomicWithFile :: FilePath -> (Handle -> IO ()) -> IO () atomicWithFile = atomicWithFileAndMaybeMode Nothing -- | A general version of 'atomicWriteFileWithMode' atomicWithFileAndMode :: FileMode -> FilePath -> (Handle -> IO ()) -> IO () atomicWithFileAndMode = atomicWithFileAndMaybeMode . Just -- | Helper function atomicWithFileAndMaybeMode :: Maybe FileMode -> FilePath -> (Handle -> IO ()) -> IO () atomicWithFileAndMaybeMode mmode path action = tempFileFor path >>= \(tmpPath, h) -> hSetBinaryMode h True >> action h >> closeAndRename h tmpPath path >> maybeSetFileMode path mmode atomic-write-0.2.0.7/src/System/AtomicWrite/Writer/Text.hs0000644000000000000000000000315313565556026021525 0ustar0000000000000000-- | -- Module : System.AtomicWrite.Writer.Text -- Copyright : © 2015-2019 Stack Builders Inc. -- License : MIT -- -- Maintainer : Stack Builders -- Stability : experimental -- Portability : portable -- -- Provides functionality to dump the contents of a Text -- to a file. module System.AtomicWrite.Writer.Text (atomicWriteFile, atomicWriteFileWithMode) where import System.AtomicWrite.Internal (atomicWriteFileMaybeModeText) import Data.Text (Text) import Data.Text.IO (hPutStr) import System.Posix.Types (FileMode) -- | Creates a file atomically on POSIX-compliant -- systems while preserving permissions. atomicWriteFile :: FilePath -- ^ The path where the file will be updated or created -> Text -- ^ The content to write to the file -> IO () atomicWriteFile = atomicWriteFileMaybeMode Nothing -- | Creates or modifies a file atomically on -- POSIX-compliant systems and updates permissions atomicWriteFileWithMode :: FileMode -- ^ The mode to set the file to -> FilePath -- ^ The path where the file will be updated or created -> Text -- ^ The content to write to the file -> IO () atomicWriteFileWithMode = atomicWriteFileMaybeMode . Just -- Helper Function atomicWriteFileMaybeMode :: Maybe FileMode -- ^ The mode to set the file to -> FilePath -- ^ The path where the file will be updated or created -> Text -- ^ The content to write to the file -> IO () atomicWriteFileMaybeMode mmode path = atomicWriteFileMaybeModeText mmode path hPutStr atomic-write-0.2.0.7/src/System/AtomicWrite/Writer/Text/Binary.hs0000644000000000000000000000321413565556026022747 0ustar0000000000000000-- | -- Module : System.AtomicWrite.Writer.Text.Binary -- Copyright : © 2015-2019 Stack Builders Inc. -- License : MIT -- -- Maintainer : Stack Builders -- Stability : experimental -- Portability : portable -- -- Provides functionality to dump the contents of a Text -- to a file in binary mode. module System.AtomicWrite.Writer.Text.Binary (atomicWriteFile, atomicWriteFileWithMode) where import System.AtomicWrite.Internal (atomicWriteFileMaybeModeBinary) import Data.Text (Text) import Data.Text.IO (hPutStr) import System.Posix.Types (FileMode) -- | Creates a file atomically on POSIX-compliant -- systems while preserving permissions. atomicWriteFile :: FilePath -- ^ The path where the file will be updated or created -> Text -- ^ The content to write to the file -> IO () atomicWriteFile = atomicWriteFileMaybeMode Nothing -- | Creates or modifies a file atomically on -- POSIX-compliant systems and updates permissions atomicWriteFileWithMode :: FileMode -- ^ The mode to set the file to -> FilePath -- ^ The path where the file will be updated or created -> Text -- ^ The content to write to the file -> IO () atomicWriteFileWithMode = atomicWriteFileMaybeMode . Just -- Helper Function atomicWriteFileMaybeMode :: Maybe FileMode -- ^ The mode to set the file to -> FilePath -- ^ The path where the file will be updated or created -> Text -- ^ The content to write to the file -> IO () atomicWriteFileMaybeMode mmode path = atomicWriteFileMaybeModeBinary mmode path hPutStr atomic-write-0.2.0.7/src/System/AtomicWrite/Writer/LazyText.hs0000644000000000000000000000316313565556026022366 0ustar0000000000000000-- | -- Module : System.AtomicWrite.Writer.LazyText -- Copyright : © 2015-2019 Stack Builders Inc. -- License : MIT -- -- Maintainer : Stack Builders -- Stability : experimental -- Portability : portable -- -- Provides functionality to dump the contents of a Text -- to a file. module System.AtomicWrite.Writer.LazyText (atomicWriteFile, atomicWriteFileWithMode) where import System.AtomicWrite.Internal (atomicWriteFileMaybeModeText) import Data.Text.Lazy (Text) import Data.Text.Lazy.IO (hPutStr) import System.Posix.Types (FileMode) -- | Creates a file atomically on POSIX-compliant -- systems while preserving permissions. atomicWriteFile :: FilePath -- ^ The path where the file will be updated or created -> Text -- ^ The content to write to the file -> IO () atomicWriteFile = atomicWriteFileMaybeMode Nothing -- | Creates or modifies a file atomically on -- POSIX-compliant systems and updates permissions atomicWriteFileWithMode :: FileMode -- ^ The mode to set the file to -> FilePath -- ^ The path where the file will be updated or created -> Text -- ^ The content to write to the file -> IO () atomicWriteFileWithMode = atomicWriteFileMaybeMode . Just -- Helper Function atomicWriteFileMaybeMode :: Maybe FileMode -- ^ The mode to set the file to -> FilePath -- ^ The path where the file will be updated or created -> Text -- ^ The content to write to the file -> IO () atomicWriteFileMaybeMode mmode path = atomicWriteFileMaybeModeText mmode path hPutStr atomic-write-0.2.0.7/src/System/AtomicWrite/Writer/LazyText/Binary.hs0000644000000000000000000000322313565556026023607 0ustar0000000000000000-- | -- Module : System.AtomicWrite.Writer.LazyText.Binary -- Copyright : © 2015-2019 Stack Builders Inc. -- License : MIT -- -- Maintainer : Stack Builders -- Stability : experimental -- Portability : portable -- -- Provides functionality to dump the contents of a Text -- to a file in binary mode. module System.AtomicWrite.Writer.LazyText.Binary (atomicWriteFile, atomicWriteFileWithMode) where import System.AtomicWrite.Internal (atomicWriteFileMaybeModeBinary) import Data.Text.Lazy (Text) import Data.Text.Lazy.IO (hPutStr) import System.Posix.Types (FileMode) -- | Creates a file atomically on POSIX-compliant -- systems while preserving permissions. atomicWriteFile :: FilePath -- ^ The path where the file will be updated or created -> Text -- ^ The content to write to the file -> IO () atomicWriteFile = atomicWriteFileMaybeMode Nothing -- | Creates or modifies a file atomically on -- POSIX-compliant systems and updates permissions atomicWriteFileWithMode :: FileMode -- ^ The mode to set the file to -> FilePath -- ^ The path where the file will be updated or created -> Text -- ^ The content to write to the file -> IO () atomicWriteFileWithMode = atomicWriteFileMaybeMode . Just -- Helper Function atomicWriteFileMaybeMode :: Maybe FileMode -- ^ The mode to set the file to -> FilePath -- ^ The path where the file will be updated or created -> Text -- ^ The content to write to the file -> IO () atomicWriteFileMaybeMode mmode path = atomicWriteFileMaybeModeBinary mmode path hPutStr atomic-write-0.2.0.7/src/System/AtomicWrite/Internal.hs0000644000000000000000000000620013565556026021075 0ustar0000000000000000-- | -- Module : System.AtomicWrite.Internal -- Copyright : © 2015-2019 Stack Builders Inc. -- License : MIT -- -- Maintainer : Stack Builders -- Stability : experimental -- Portability : portable -- -- Provides functionality to create a temporary file with correct permissions -- atomically. module System.AtomicWrite.Internal where import System.Directory (doesFileExist, renameFile) import System.FilePath (takeDirectory) import System.IO (Handle, hClose, hSetBinaryMode, openTempFile, openTempFileWithDefaultPermissions) import System.Posix.Types (FileMode) import System.PosixCompat.Files (fileMode, getFileStatus, setFileMode) -- | Returns a temporary file with permissions correctly set. Chooses -- either previously-set permissions if the file that we're writing -- to existed, or permissions following the current umask. tempFileFor :: FilePath -- ^ The target filepath that we will replace atomically. -> IO (FilePath, Handle) tempFileFor targetFilePath = doesFileExist targetFilePath >>= tmpFile targetFilePath (takeDirectory targetFilePath) "atomic.write" where tmpFile :: FilePath -> FilePath -> String -> Bool -> IO (FilePath, Handle) tmpFile targetPath workingDirectory template previousExisted = if previousExisted then openTempFile workingDirectory template >>= \(tmpPath, handle) -> getFileStatus targetPath >>= setFileMode tmpPath . fileMode >> return (tmpPath, handle) else openTempFileWithDefaultPermissions workingDirectory template closeAndRename :: Handle -> FilePath -> FilePath -> IO () closeAndRename tmpHandle tempFile destFile = hClose tmpHandle >> renameFile tempFile destFile maybeSetFileMode :: FilePath -> Maybe FileMode -> IO () maybeSetFileMode path = maybe ( return () ) ( \mode -> setFileMode path mode ) -- Helper Function atomicWriteFileMaybeModeText :: Maybe FileMode -- ^ The mode to set the file to -> FilePath -- ^ The path where the file will be updated or created -> (Handle -> a -> IO ()) -- ^ The function to use to write on the file -> a -- ^ The content to write to the file -> IO () atomicWriteFileMaybeModeText mmode path hF text = tempFileFor path >>= \(tmpPath, h) -> hSetBinaryMode h False >> hF h text >> closeAndRename h tmpPath path >> maybeSetFileMode path mmode -- Helper Function atomicWriteFileMaybeModeBinary :: Maybe FileMode -- ^ The mode to set the file to -> FilePath -- ^ The path where the file will be updated or created -> (Handle -> a -> IO ()) -- ^ The function to use to write on the file -> a -- ^ The content to write to the file -> IO () atomicWriteFileMaybeModeBinary mmode path hF text = tempFileFor path >>= \(tmpPath, h) -> hSetBinaryMode h True >> hF h text >> closeAndRename h tmpPath path >> maybeSetFileMode path mmode atomic-write-0.2.0.7/spec/Spec.hs0000644000000000000000000000005413565556026014644 0ustar0000000000000000{-# OPTIONS_GHC -F -pgmF hspec-discover #-} atomic-write-0.2.0.7/spec/System/AtomicWrite/Writer/ByteStringSpec.hs0000644000000000000000000001223413565556026023651 0ustar0000000000000000module System.AtomicWrite.Writer.ByteStringSpec (spec) where import Test.Hspec (Spec, describe, it, shouldBe) import System.AtomicWrite.Writer.ByteString (atomicWriteFile, atomicWriteFileWithMode) import System.FilePath.Posix (joinPath) import System.IO.Temp (withSystemTempDirectory) import System.PosixCompat.Files (fileMode, getFileStatus, setFileCreationMask, setFileMode) import Data.ByteString.Char8 (pack) spec :: Spec spec = do describe "atomicWriteFile" $ do it "writes contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFile path $ pack "just testing" contents <- readFile path contents `shouldBe` "just testing" it "preserves the permissions of original file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFile filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100644 it "creates a new file with permissions based on active umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] sampleFilePath = joinPath [tmpDir, "sampleFile"] -- Set somewhat distinctive defaults for test _ <- setFileCreationMask 0o100171 -- We don't know what the default file permissions are, so create a -- file to sample them. writeFile sampleFilePath "I'm being written to sample permissions" newStat <- getFileStatus sampleFilePath fileMode newStat `shouldBe` 0o100606 atomicWriteFile filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- The default tempfile permissions are 0600, so this fails unless we -- make sure that the default umask is relied on for creation of the -- tempfile. fileMode resultStat `shouldBe` 0o100606 describe "atomicWriteFileWithMode" $ do it "writes contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFileWithMode 0o100777 path $ pack "just testing" contents <- readFile path contents `shouldBe` "just testing" it "changes the permissions of a previously created file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFileWithMode 0o100655 filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100655 it "creates a new file with specified permissions" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] atomicWriteFileWithMode 0o100606 filePath $ pack "new contents" resultStat <- getFileStatus filePath fileMode resultStat `shouldBe` 0o100606 atomic-write-0.2.0.7/spec/System/AtomicWrite/Writer/ByteString/BinarySpec.hs0000644000000000000000000001235713565556026025103 0ustar0000000000000000module System.AtomicWrite.Writer.ByteString.BinarySpec (spec) where import Test.Hspec (Spec, describe, it, shouldBe) import System.AtomicWrite.Writer.ByteString.Binary (atomicWriteFile, atomicWriteFileWithMode) import System.FilePath.Posix (joinPath) import System.IO.Temp (withSystemTempDirectory) import System.PosixCompat.Files (fileMode, getFileStatus, setFileCreationMask, setFileMode) import Data.ByteString.Char8 (pack) spec :: Spec spec = do describe "atomicWriteFile" $ do it "writes the contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFile path $ pack "just testing" contents <- readFile path contents `shouldBe` "just testing" it "preserves the permissions of original file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFile filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100644 it "creates a new file with permissions based on active umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] sampleFilePath = joinPath [tmpDir, "sampleFile"] -- Set somewhat distinctive defaults for test _ <- setFileCreationMask 0o100171 -- We don't know what the default file permissions are, so create a -- file to sample them. writeFile sampleFilePath "I'm being written to sample permissions" newStat <- getFileStatus sampleFilePath fileMode newStat `shouldBe` 0o100606 atomicWriteFile filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- The default tempfile permissions are 0600, so this fails unless we -- make sure that the default umask is relied on for creation of the -- tempfile. fileMode resultStat `shouldBe` 0o100606 describe "atomicWriteFileWithMode" $ do it "writes contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFileWithMode 0o100777 path $ pack "just testing" contents <- readFile path contents `shouldBe` "just testing" it "changes the permissions of a previously created file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFileWithMode 0o100655 filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100655 it "creates a new file with specified permissions" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] atomicWriteFileWithMode 0o100606 filePath $ pack "new contents" resultStat <- getFileStatus filePath fileMode resultStat `shouldBe` 0o100606 atomic-write-0.2.0.7/spec/System/AtomicWrite/Writer/ByteStringBuilderSpec.hs0000644000000000000000000001172513565556026025164 0ustar0000000000000000module System.AtomicWrite.Writer.ByteStringBuilderSpec (spec) where import Test.Hspec (it, describe, shouldBe, Spec) import System.AtomicWrite.Writer.ByteStringBuilder (atomicWriteFile, atomicWriteFileWithMode) import System.IO.Temp (withSystemTempDirectory) import System.FilePath.Posix (joinPath) import System.PosixCompat.Files (setFileMode, setFileCreationMask, getFileStatus, fileMode) import Data.ByteString.Builder (lazyByteString) import Data.ByteString.Lazy.Char8 (pack) spec :: Spec spec = do describe "atomicWriteFile" $ do it "writes contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFile path $ lazyByteString $ pack "just testing" contents <- readFile path contents `shouldBe` "just testing" it "preserves the permissions of original file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFile filePath $ lazyByteString $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100644 it "creates a new file with permissions based on active umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] sampleFilePath = joinPath [tmpDir, "sampleFile"] -- Set somewhat distinctive defaults for test _ <- setFileCreationMask 0o100171 -- We don't know what the default file permissions are, so create a -- file to sample them. writeFile sampleFilePath "I'm being written to sample permissions" newStat <- getFileStatus sampleFilePath fileMode newStat `shouldBe` 0o100606 atomicWriteFile filePath $ lazyByteString $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- The default tempfile permissions are 0600, so this fails unless we -- make sure that the default umask is relied on for creation of the -- tempfile. fileMode resultStat `shouldBe` 0o100606 describe "atomicWriteFileWithMode" $ do it "writes contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFileWithMode 0o100777 path $ lazyByteString $ pack "just testing" contents <- readFile path contents `shouldBe` "just testing" it "changes the permissions of a previously created file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFileWithMode 0o100655 filePath $ lazyByteString $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100655 it "creates a new file with specified permissions" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] atomicWriteFileWithMode 0o100606 filePath $ lazyByteString $ pack "new contents" resultStat <- getFileStatus filePath fileMode resultStat `shouldBe` 0o100606 atomic-write-0.2.0.7/spec/System/AtomicWrite/Writer/LazyByteStringSpec.hs0000644000000000000000000001147013565556026024512 0ustar0000000000000000module System.AtomicWrite.Writer.LazyByteStringSpec (spec) where import Test.Hspec (it, describe, shouldBe, Spec) import System.AtomicWrite.Writer.LazyByteString (atomicWriteFile, atomicWriteFileWithMode) import System.IO.Temp (withSystemTempDirectory) import System.FilePath.Posix (joinPath) import System.PosixCompat.Files (setFileMode, setFileCreationMask, getFileStatus, fileMode) import Data.ByteString.Lazy.Char8 (pack) spec :: Spec spec = do describe "atomicWriteFile" $ do it "writes contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFile path $ pack "just testing" contents <- readFile path contents `shouldBe` "just testing" it "preserves the permissions of original file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFile filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100644 it "creates a new file with permissions based on active umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] sampleFilePath = joinPath [tmpDir, "sampleFile"] -- Set somewhat distinctive defaults for test _ <- setFileCreationMask 0o100171 -- We don't know what the default file permissions are, so create a -- file to sample them. writeFile sampleFilePath "I'm being written to sample permissions" newStat <- getFileStatus sampleFilePath fileMode newStat `shouldBe` 0o100606 atomicWriteFile filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- The default tempfile permissions are 0600, so this fails unless we -- make sure that the default umask is relied on for creation of the -- tempfile. fileMode resultStat `shouldBe` 0o100606 describe "atomicWriteFileWithMode" $ do it "writes contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFileWithMode 0o100777 path $ pack "just testing" contents <- readFile path contents `shouldBe` "just testing" it "changes the permissions of a previously created file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFileWithMode 0o100655 filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100655 it "creates a new file with specified permissions" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] atomicWriteFileWithMode 0o100606 filePath $ pack "new contents" resultStat <- getFileStatus filePath fileMode resultStat `shouldBe` 0o100606 atomic-write-0.2.0.7/spec/System/AtomicWrite/Writer/LazyByteString/BinarySpec.hs0000644000000000000000000001263013565556026025735 0ustar0000000000000000module System.AtomicWrite.Writer.LazyByteString.BinarySpec (spec) where import Test.Hspec (Spec, describe, it, shouldBe) import System.AtomicWrite.Writer.LazyByteString.Binary (atomicWriteFile, atomicWriteFileWithMode) import System.FilePath.Posix (joinPath) import System.IO.Temp (withSystemTempDirectory) import System.PosixCompat.Files (fileMode, getFileStatus, setFileCreationMask, setFileMode) import Data.ByteString.Lazy.Char8 (pack) spec :: Spec spec = do describe "atomicWriteFile" $ do it "writes contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFile path $ pack "just testing" contents <- readFile path contents `shouldBe` "just testing" it "preserves the permissions of original file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFile filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100644 it "creates a new file with permissions based on active umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] sampleFilePath = joinPath [tmpDir, "sampleFile"] -- Set somewhat distinctive defaults for test _ <- setFileCreationMask 0o100171 -- We don't know what the default file permissions are, so create a -- file to sample them. writeFile sampleFilePath "I'm being written to sample permissions" newStat <- getFileStatus sampleFilePath fileMode newStat `shouldBe` 0o100606 atomicWriteFile filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- The default tempfile permissions are 0600, so this fails unless we -- make sure that the default umask is relied on for creation of the -- tempfile. fileMode resultStat `shouldBe` 0o100606 describe "atomicWriteFileWithMode" $ do it "writes contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFileWithMode 0o100777 path $ pack "just testing" contents <- readFile path contents `shouldBe` "just testing" it "changes the permissions of a previously created file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFileWithMode 0o100655 filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100655 it "creates a new file with specified permissions" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] atomicWriteFileWithMode 0o100606 filePath $ pack "new contents" resultStat <- getFileStatus filePath fileMode resultStat `shouldBe` 0o100606 atomic-write-0.2.0.7/spec/System/AtomicWrite/Writer/StringSpec.hs0000644000000000000000000001202313565556026023021 0ustar0000000000000000module System.AtomicWrite.Writer.StringSpec (spec) where import Test.Hspec (Spec, describe, it, shouldBe) import System.AtomicWrite.Writer.String (atomicWriteFile, atomicWriteFileWithMode) import System.FilePath (joinPath) import System.IO.Temp (withSystemTempDirectory) import System.PosixCompat.Files (fileMode, getFileStatus, setFileCreationMask, setFileMode) {-# ANN module "HLint: ignore Reduce duplication" #-} spec :: Spec spec = do describe "atomicWriteFile" $ do it "writes contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFile path "just testing" contents <- readFile path contents `shouldBe` "just testing" it "preserves the permissions of original file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFile filePath "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100644 it "creates a new file with permissions based on active umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] sampleFilePath = joinPath [tmpDir, "sampleFile"] -- Set somewhat distinctive defaults for test _ <- setFileCreationMask 0o100171 -- We don't know what the default file permissions are, so create a -- file to sample them. writeFile sampleFilePath "I'm being written to sample permissions" newStat <- getFileStatus sampleFilePath fileMode newStat `shouldBe` 0o100606 atomicWriteFile filePath "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- The default tempfile permissions are 0600, so this fails unless we -- make sure that the default umask is relied on for creation of the -- tempfile. fileMode resultStat `shouldBe` 0o100606 describe "atomicWriteFileWithMode" $ do it "writes contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFileWithMode 0o100777 path "just testing" contents <- readFile path contents `shouldBe` "just testing" it "changes the permissions of a previously created file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFileWithMode 0o100655 filePath "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100655 it "creates a new file with specified permissions" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] atomicWriteFileWithMode 0o100606 filePath "new contents" resultStat <- getFileStatus filePath fileMode resultStat `shouldBe` 0o100606 atomic-write-0.2.0.7/spec/System/AtomicWrite/Writer/String/BinarySpec.hs0000644000000000000000000001221413565556026024247 0ustar0000000000000000module System.AtomicWrite.Writer.String.BinarySpec (spec) where import Test.Hspec (Spec, describe, it, shouldBe) import System.AtomicWrite.Writer.String.Binary (atomicWriteFile, atomicWriteFileWithMode) import System.FilePath (joinPath) import System.IO.Temp (withSystemTempDirectory) import System.PosixCompat.Files (fileMode, getFileStatus, setFileCreationMask, setFileMode) {-# ANN module "HLint: ignore Reduce duplication" #-} spec :: Spec spec = do describe "atomicWriteFile" $ do it "writes contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFile path "just testing" contents <- readFile path contents `shouldBe` "just testing" it "preserves the permissions of original file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFile filePath "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100644 it "creates a new file with permissions based on active umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] sampleFilePath = joinPath [tmpDir, "sampleFile"] -- Set somewhat distinctive defaults for test _ <- setFileCreationMask 0o100171 -- We don't know what the default file permissions are, so create a -- file to sample them. writeFile sampleFilePath "I'm being written to sample permissions" newStat <- getFileStatus sampleFilePath fileMode newStat `shouldBe` 0o100606 atomicWriteFile filePath "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- The default tempfile permissions are 0600, so this fails unless we -- make sure that the default umask is relied on for creation of the -- tempfile. fileMode resultStat `shouldBe` 0o100606 describe "atomicWriteFileWithMode" $ do it "writes contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFileWithMode 0o100777 path "just testing" contents <- readFile path contents `shouldBe` "just testing" it "changes the permissions of a previously created file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFileWithMode 0o100655 filePath "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100655 it "creates a new file with specified permissions" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] atomicWriteFileWithMode 0o100606 filePath "new contents" resultStat <- getFileStatus filePath fileMode resultStat `shouldBe` 0o100606 atomic-write-0.2.0.7/spec/System/AtomicWrite/Writer/TextSpec.hs0000644000000000000000000001142313565556026022502 0ustar0000000000000000module System.AtomicWrite.Writer.TextSpec (spec) where import Test.Hspec (it, describe, shouldBe, Spec) import System.AtomicWrite.Writer.Text (atomicWriteFile, atomicWriteFileWithMode) import System.IO.Temp (withSystemTempDirectory) import System.FilePath.Posix (joinPath) import System.PosixCompat.Files (setFileMode, setFileCreationMask, getFileStatus, fileMode) import Data.Text (pack) spec :: Spec spec = do describe "atomicWriteFile" $ do it "writes contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFile path $ pack "just testing" contents <- readFile path contents `shouldBe` "just testing" it "preserves the permissions of original file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFile filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100644 it "creates a new file with permissions based on active umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] sampleFilePath = joinPath [tmpDir, "sampleFile"] -- Set somewhat distinctive defaults for test _ <- setFileCreationMask 0o100171 -- We don't know what the default file permissions are, so create a -- file to sample them. writeFile sampleFilePath "I'm being written to sample permissions" newStat <- getFileStatus sampleFilePath fileMode newStat `shouldBe` 0o100606 atomicWriteFile filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- The default tempfile permissions are 0600, so this fails unless we -- make sure that the default umask is relied on for creation of the -- tempfile. fileMode resultStat `shouldBe` 0o100606 describe "atomicWriteFileWithMode" $ do it "writes contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFileWithMode 0o100777 path $ pack "just testing" contents <- readFile path contents `shouldBe` "just testing" it "changes the permissions of a previously created file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFileWithMode 0o100655 filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100655 it "creates a new file with specified permissions" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] atomicWriteFileWithMode 0o100606 filePath $ pack "new contents" resultStat <- getFileStatus filePath fileMode resultStat `shouldBe` 0o100606 atomic-write-0.2.0.7/spec/System/AtomicWrite/Writer/Text/BinarySpec.hs0000644000000000000000000001224613565556026023732 0ustar0000000000000000module System.AtomicWrite.Writer.Text.BinarySpec (spec) where import Test.Hspec (Spec, describe, it, shouldBe) import System.AtomicWrite.Writer.Text.Binary (atomicWriteFile, atomicWriteFileWithMode) import System.FilePath.Posix (joinPath) import System.IO.Temp (withSystemTempDirectory) import System.PosixCompat.Files (fileMode, getFileStatus, setFileCreationMask, setFileMode) import Data.Text (pack) spec :: Spec spec = do describe "atomicWriteFile" $ do it "writes contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFile path $ pack "just testing" contents <- readFile path contents `shouldBe` "just testing" it "preserves the permissions of original file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFile filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100644 it "creates a new file with permissions based on active umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] sampleFilePath = joinPath [tmpDir, "sampleFile"] -- Set somewhat distinctive defaults for test _ <- setFileCreationMask 0o100171 -- We don't know what the default file permissions are, so create a -- file to sample them. writeFile sampleFilePath "I'm being written to sample permissions" newStat <- getFileStatus sampleFilePath fileMode newStat `shouldBe` 0o100606 atomicWriteFile filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- The default tempfile permissions are 0600, so this fails unless we -- make sure that the default umask is relied on for creation of the -- tempfile. fileMode resultStat `shouldBe` 0o100606 describe "atomicWriteFileWithMode" $ do it "writes contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFileWithMode 0o100777 path $ pack "just testing" contents <- readFile path contents `shouldBe` "just testing" it "changes the permissions of a previously created file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFileWithMode 0o100655 filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100655 it "creates a new file with specified permissions" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] atomicWriteFileWithMode 0o100606 filePath $ pack "new contents" resultStat <- getFileStatus filePath fileMode resultStat `shouldBe` 0o100606 atomic-write-0.2.0.7/spec/System/AtomicWrite/Writer/LazyTextSpec.hs0000644000000000000000000001144013565556026023341 0ustar0000000000000000module System.AtomicWrite.Writer.LazyTextSpec (spec) where import Test.Hspec (it, describe, shouldBe, Spec) import System.AtomicWrite.Writer.LazyText (atomicWriteFile, atomicWriteFileWithMode) import System.IO.Temp (withSystemTempDirectory) import System.FilePath.Posix (joinPath) import System.PosixCompat.Files (setFileMode, setFileCreationMask, getFileStatus, fileMode) import Data.Text.Lazy (pack) spec :: Spec spec = do describe "atomicWriteFile" $ do it "writes contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFile path $ pack "just testing" contents <- readFile path contents `shouldBe` "just testing" it "preserves the permissions of original file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFile filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100644 it "creates a new file with permissions based on active umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] sampleFilePath = joinPath [tmpDir, "sampleFile"] -- Set somewhat distinctive defaults for test _ <- setFileCreationMask 0o100171 -- We don't know what the default file permissions are, so create a -- file to sample them. writeFile sampleFilePath "I'm being written to sample permissions" newStat <- getFileStatus sampleFilePath fileMode newStat `shouldBe` 0o100606 atomicWriteFile filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- The default tempfile permissions are 0600, so this fails unless we -- make sure that the default umask is relied on for creation of the -- tempfile. fileMode resultStat `shouldBe` 0o100606 describe "atomicWriteFileWithMode" $ do it "writes contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFileWithMode 0o100777 path $ pack "just testing" contents <- readFile path contents `shouldBe` "just testing" it "changes the permissions of a previously created file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFileWithMode 0o100655 filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100655 it "creates a new file with specified permissions" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] atomicWriteFileWithMode 0o100606 filePath $ pack "new contents" resultStat <- getFileStatus filePath fileMode resultStat `shouldBe` 0o100606 atomic-write-0.2.0.7/spec/System/AtomicWrite/Writer/LazyText/BinarySpec.hs0000644000000000000000000001232213565556026024565 0ustar0000000000000000module System.AtomicWrite.Writer.LazyText.BinarySpec (spec) where import Test.Hspec (Spec, describe, it, shouldBe) import System.AtomicWrite.Writer.LazyText.Binary (atomicWriteFile, atomicWriteFileWithMode) import System.FilePath.Posix (joinPath) import System.IO.Temp (withSystemTempDirectory) import System.PosixCompat.Files (fileMode, getFileStatus, setFileCreationMask, setFileMode) import Data.Text.Lazy (pack) spec :: Spec spec = do describe "atomicWriteFile" $ do it "writes contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFile path $ pack "just testing" contents <- readFile path contents `shouldBe` "just testing" it "preserves the permissions of original file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFile filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100644 it "creates a new file with permissions based on active umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] sampleFilePath = joinPath [tmpDir, "sampleFile"] -- Set somewhat distinctive defaults for test _ <- setFileCreationMask 0o100171 -- We don't know what the default file permissions are, so create a -- file to sample them. writeFile sampleFilePath "I'm being written to sample permissions" newStat <- getFileStatus sampleFilePath fileMode newStat `shouldBe` 0o100606 atomicWriteFile filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- The default tempfile permissions are 0600, so this fails unless we -- make sure that the default umask is relied on for creation of the -- tempfile. fileMode resultStat `shouldBe` 0o100606 describe "atomicWriteFileWithMode" $ do it "writes contents to a file" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let path = joinPath [ tmpDir, "writeTest.tmp" ] atomicWriteFileWithMode 0o100777 path $ pack "just testing" contents <- readFile path contents `shouldBe` "just testing" it "changes the permissions of a previously created file, regardless of umask" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] writeFile filePath "initial contents" setFileMode filePath 0o100644 newStat <- getFileStatus filePath fileMode newStat `shouldBe` 0o100644 -- New files are created with 100600 perms. _ <- setFileCreationMask 0o100066 -- Create a new file once different mask is set and make sure that mask -- is applied. writeFile (joinPath [tmpDir, "sanityCheck"]) "with sanity check mask" sanityCheckStat <- getFileStatus $ joinPath [tmpDir, "sanityCheck"] fileMode sanityCheckStat `shouldBe` 0o100600 -- Since we move, this makes the new file assume the filemask of 0600 atomicWriteFileWithMode 0o100655 filePath $ pack "new contents" resultStat <- getFileStatus filePath -- reset mask to not break subsequent specs _ <- setFileCreationMask 0o100022 -- Fails when using atomic mv command unless apply perms on initial file fileMode resultStat `shouldBe` 0o100655 it "creates a new file with specified permissions" $ withSystemTempDirectory "atomicFileTest" $ \tmpDir -> do let filePath = joinPath [tmpDir, "testFile"] atomicWriteFileWithMode 0o100606 filePath $ pack "new contents" resultStat <- getFileStatus filePath fileMode resultStat `shouldBe` 0o100606 atomic-write-0.2.0.7/LICENSE0000644000000000000000000000205413565556026013473 0ustar0000000000000000Copyright (c) 2015-2019 Stack Builders Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. atomic-write-0.2.0.7/Setup.hs0000644000000000000000000000005613565556026014122 0ustar0000000000000000import Distribution.Simple main = defaultMain atomic-write-0.2.0.7/atomic-write.cabal0000644000000000000000000001075013565573374016065 0ustar0000000000000000name: atomic-write version: 0.2.0.7 synopsis: Atomically write to a file homepage: https://github.com/stackbuilders/atomic-write description: . Atomically write to a file on POSIX-compliant systems while preserving permissions. . On most Unix systems, `mv` is an atomic operation. This makes it simple to write to a file atomically just by using the mv operation. However, this will destroy the permissions on the original file. This library does the following to preserve permissions while atomically writing to a file: . * If an original file exists, take those permissions and apply them to the temp file before `mv`ing the file into place. . * If the original file does not exist, create a following with default permissions (based on the currently-active umask). . This way, when the file is `mv`'ed into place, the permissions will be the ones held by the original file. . This library is based on similar implementations found in common libraries in Ruby and Python: . * . * . * . To use `atomic-write`, import the module corresponding to the type you wish to write atomically, e.g., to write a (strict) ByteString atomically: . > import System.AtomicWrite.Writer.ByteString . Then you can use the atomicWriteFile function that accepts a `FilePath` and a `ByteString`, e.g.: . > atomicWriteFile myFilePath myByteString license: MIT license-file: LICENSE author: Justin Leitgeb maintainer: support@stackbuilders.com copyright: 2015-2019 Stack Builders Inc. category: System build-type: Simple cabal-version: >=1.10 bug-reports: https://github.com/stackbuilders/atomic-write/issues library exposed-modules: System.AtomicWrite.Writer.ByteString , System.AtomicWrite.Writer.ByteString.Binary , System.AtomicWrite.Writer.ByteStringBuilder , System.AtomicWrite.Writer.LazyByteString , System.AtomicWrite.Writer.LazyByteString.Binary , System.AtomicWrite.Writer.String , System.AtomicWrite.Writer.String.Binary , System.AtomicWrite.Writer.Text , System.AtomicWrite.Writer.Text.Binary , System.AtomicWrite.Writer.LazyText , System.AtomicWrite.Writer.LazyText.Binary other-modules: System.AtomicWrite.Internal build-depends: base >= 4.5 && < 5.0 , temporary , unix-compat , directory , filepath , text , bytestring >= 0.10.4 hs-source-dirs: src default-language: Haskell2010 ghc-options: -Wall test-suite atomic-write-test type: exitcode-stdio-1.0 hs-source-dirs: spec main-is: Spec.hs other-modules: System.AtomicWrite.Writer.ByteStringSpec , System.AtomicWrite.Writer.ByteString.BinarySpec , System.AtomicWrite.Writer.ByteStringBuilderSpec , System.AtomicWrite.Writer.LazyByteStringSpec , System.AtomicWrite.Writer.LazyByteString.BinarySpec , System.AtomicWrite.Writer.StringSpec , System.AtomicWrite.Writer.String.BinarySpec , System.AtomicWrite.Writer.TextSpec , System.AtomicWrite.Writer.Text.BinarySpec , System.AtomicWrite.Writer.LazyTextSpec , System.AtomicWrite.Writer.LazyText.BinarySpec build-depends: base >= 4.5 && < 5.0 , atomic-write , temporary , unix-compat , filepath , text , bytestring >= 0.10.4 , hspec default-language: Haskell2010 ghc-options: -Wall source-repository head type: git location: git@github.com:stackbuilders/atomic-write.git