atomic-write 0.1.0.1 → 0.2.0.0
raw patch · 8 files changed
+149/−69 lines, 8 filesdep +bytestringdep +textPVP ok
version bump matches the API change (PVP)
Dependencies added: bytestring, text
API changes (from Hackage documentation)
- System.AtomicWrite: atomicWriteFile :: FilePath -> String -> IO ()
+ System.AtomicWrite.Writer.ByteString: atomicWriteFile :: FilePath -> ByteString -> IO ()
+ System.AtomicWrite.Writer.ByteStringBuilder: atomicWriteFile :: FilePath -> Builder -> IO ()
+ System.AtomicWrite.Writer.LazyByteString: atomicWriteFile :: FilePath -> ByteString -> IO ()
+ System.AtomicWrite.Writer.String: atomicWriteFile :: FilePath -> String -> IO ()
+ System.AtomicWrite.Writer.Text: atomicWriteFile :: FilePath -> Text -> IO ()
Files
- atomic-write.cabal +24/−6
- src/System/AtomicWrite.hs +0/−63
- src/System/AtomicWrite/Internal.hs +41/−0
- src/System/AtomicWrite/Writer/ByteString.hs +14/−0
- src/System/AtomicWrite/Writer/ByteStringBuilder.hs +26/−0
- src/System/AtomicWrite/Writer/LazyByteString.hs +14/−0
- src/System/AtomicWrite/Writer/String.hs +14/−0
- src/System/AtomicWrite/Writer/Text.hs +16/−0
atomic-write.cabal view
@@ -1,5 +1,5 @@ name: atomic-write-version: 0.1.0.1+version: 0.2.0.0 synopsis: Atomically write to a file description:@@ -30,8 +30,18 @@ . * <https://github.com/sashka/atomicfile There is a python library for atomically updating a file> .- Note that at this time Windows is not supported, however we would appreciate+ At this time Windows is not supported, however we would appreciate contributions to the <http://github.com/stackbuilders/atomic-write github repository>.+ .+ 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 atomicWrite function that accepts a `FilePath` and a+ `ByteString`, e.g.:+ .+ > atomicWrite myFilePath myByteString license: MIT license-file: LICENSE author: Justin Leitgeb@@ -39,18 +49,24 @@ copyright: 2015 Stack Builders Inc. category: System build-type: Simple--- extra-source-files: cabal-version: >=1.10 library- exposed-modules: System.AtomicWrite- -- other-modules:- -- other-extensions:+ exposed-modules: System.AtomicWrite.Writer.ByteString+ , System.AtomicWrite.Writer.ByteStringBuilder+ , System.AtomicWrite.Writer.LazyByteString+ , System.AtomicWrite.Writer.String+ , System.AtomicWrite.Writer.Text++ other-modules: System.AtomicWrite.Internal+ build-depends: base >=4.5 && <4.8 , temporary , unix , directory , filepath+ , text+ , bytestring >= 0.10.4 hs-source-dirs: src default-language: Haskell2010@@ -66,6 +82,8 @@ , unix , directory , filepath+ , text+ , bytestring >= 0.10.4 , hspec
− src/System/AtomicWrite.hs
@@ -1,63 +0,0 @@--- |--- Module : System.AtomicWrite--- Copyright : (c) 2015 Stack Builders Inc.------ License : MIT--- Maintainer : justin@stackbuilders.com--- Stability : experimental--- Portability : GHC------ A library for atomically modifying files while preserving permissions-----module System.AtomicWrite (atomicWriteFile) where--import System.Directory (renameFile, doesFileExist)-import System.FilePath.Posix (takeDirectory)-import System.IO- (Handle, openTempFile, openTempFileWithDefaultPermissions, hPutStr, hClose)--import System.Posix.Files (setFileMode, getFileStatus, fileMode)----- | Creates 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 f txt = do- (temppath, h) <- tempFileFor f-- hPutStr h txt- hClose h-- renameFile temppath f----- | 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 -> IO (FilePath, Handle)-tempFileFor originalFilePath = do- let targetDirectory = takeDirectory originalFilePath-- doesFileExist originalFilePath >>=- tmpFile originalFilePath targetDirectory "atomic.write"-- where-- tmpFile :: FilePath -> FilePath -> String -> Bool -> IO (FilePath, Handle)- tmpFile originalPath workingDirectory template previousExisted =-- if previousExisted then do- (temppath, handle) <- openTempFile workingDirectory template-- oldStat <- getFileStatus originalPath-- setFileMode temppath $ fileMode oldStat-- return (temppath, handle)-- else- openTempFileWithDefaultPermissions workingDirectory template
+ src/System/AtomicWrite/Internal.hs view
@@ -0,0 +1,41 @@+module System.AtomicWrite.Internal (closeAndRename, tempFileFor) where++import System.Directory (doesFileExist, renameFile)+import System.Posix.Files (setFileMode, getFileStatus, fileMode)+import System.FilePath.Posix (takeDirectory)++import System.IO+ (hClose, Handle, openTempFile, openTempFileWithDefaultPermissions)++-- | 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
+ src/System/AtomicWrite/Writer/ByteString.hs view
@@ -0,0 +1,14 @@+module System.AtomicWrite.Writer.ByteString (atomicWriteFile) where++import System.AtomicWrite.Internal (closeAndRename, tempFileFor)++import Data.ByteString (ByteString, hPutStr)++-- | Creates 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 f txt =+ tempFileFor f >>= \(tmpPath, h) -> hPutStr h txt >> closeAndRename h tmpPath f
+ src/System/AtomicWrite/Writer/ByteStringBuilder.hs view
@@ -0,0 +1,26 @@+module System.AtomicWrite.Writer.ByteStringBuilder (atomicWriteFile) where++import System.AtomicWrite.Internal (closeAndRename, tempFileFor)++import Data.ByteString.Builder (hPutBuilder, Builder, hPutBuilder)++import GHC.IO.Handle (hSetBinaryMode, hSetBuffering, BufferMode (BlockBuffering))++-- | Creates 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 f builder = do+ (temppath, h) <- tempFileFor f++ -- 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 f
+ src/System/AtomicWrite/Writer/LazyByteString.hs view
@@ -0,0 +1,14 @@+module System.AtomicWrite.Writer.LazyByteString (atomicWriteFile) where++import System.AtomicWrite.Internal (closeAndRename, tempFileFor)++import Data.ByteString.Lazy (ByteString, hPutStr)++-- | Creates 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 f txt =+ tempFileFor f >>= \(tmpPath, h) -> hPutStr h txt >> closeAndRename h tmpPath f
+ src/System/AtomicWrite/Writer/String.hs view
@@ -0,0 +1,14 @@+module System.AtomicWrite.Writer.String (atomicWriteFile) where++import System.AtomicWrite.Internal (closeAndRename, tempFileFor)++import System.IO (hPutStr)++-- | Creates 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 f txt =+ tempFileFor f >>= \(tmpPath, h) -> hPutStr h txt >> closeAndRename h tmpPath f
+ src/System/AtomicWrite/Writer/Text.hs view
@@ -0,0 +1,16 @@+module System.AtomicWrite.Writer.Text (atomicWriteFile) where++import System.AtomicWrite.Internal (closeAndRename, tempFileFor)++import Data.Text (Text)++import Data.Text.IO (hPutStr)++-- | 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 f txt =+ tempFileFor f >>= \(tmpPath, h) -> hPutStr h txt >> closeAndRename h tmpPath f