conduit-extra 1.1.13.3 → 1.1.14
raw patch · 5 files changed
+61/−3 lines, 5 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
+ Data.Conduit.Binary: sinkFileCautious :: MonadResource m => FilePath -> ConduitM ByteString o m ()
Files
- ChangeLog.md +4/−0
- Data/Conduit/Binary.hs +38/−0
- Data/Conduit/Process.hs +2/−2
- conduit-extra.cabal +1/−1
- test/Data/Conduit/BinarySpec.hs +16/−0
ChangeLog.md view
@@ -1,3 +1,7 @@+## 1.1.14++* `sinkFileCautious`+ ## 1.1.13.3 * `withCheckedProcessCleanup` properly closes opened `Handle`s
Data/Conduit/Binary.hs view
@@ -22,6 +22,7 @@ , sourceHandleRangeWithBuffer -- ** Sinks , sinkFile+ , sinkFileCautious , sinkHandle , sinkIOHandle -- ** Conduits@@ -80,6 +81,11 @@ #ifndef ALLOW_UNALIGNED_ACCESS import Foreign.Marshal (alloca, copyBytes) #endif+import System.Directory (renameFile)+import System.FilePath (takeDirectory, takeFileName, (<.>))+import System.IO (hClose, openBinaryTempFile)+import Control.Exception (throwIO, catch)+import System.IO.Error (isDoesNotExistError) -- | Stream the contents of a file as binary data. --@@ -244,6 +250,38 @@ => FilePath -> Consumer S.ByteString m () sinkFile fp = sinkIOHandle (IO.openBinaryFile fp IO.WriteMode)++-- | Cautious version of 'sinkFile'. The idea here is to stream the+-- values to a temporary file in the same directory of the destination+-- file, and only on successfully writing the entire file, moves it+-- atomically to the destination path.+--+-- In the event of an exception occurring, the temporary file will be+-- deleted and no move will be made. If the application shuts down+-- without running exception handling (such as machine failure or a+-- SIGKILL), the temporary file will remain and the destination file+-- will be untouched.+--+-- @since 1.1.14+sinkFileCautious+ :: MonadResource m+ => FilePath+ -> ConduitM S.ByteString o m ()+sinkFileCautious fp =+ bracketP acquire cleanup inner+ where+ acquire = openBinaryTempFile (takeDirectory fp) (takeFileName fp <.> "tmp")+ cleanup (tmpFP, h) = do+ hClose h+ removeFile tmpFP `catch` \e ->+ if isDoesNotExistError e+ then return ()+ else throwIO e+ inner (tmpFP, h) = do+ sinkHandle h+ liftIO $ do+ hClose h+ renameFile tmpFP fp -- | Stream the contents of the input to a file, and also send it along the -- pipeline. Similar in concept to the Unix command @tee@.
Data/Conduit/Process.hs view
@@ -3,8 +3,8 @@ {-# LANGUAGE RankNTypes #-} {-# LANGUAGE CPP #-} {-# OPTIONS_GHC -fno-warn-orphans #-}--- | A full tutorial for this module is available on FP School of Haskell:--- <https://www.fpcomplete.com/user/snoyberg/library-documentation/data-conduit-process>.+-- | A full tutorial for this module is available at:+-- <https://github.com/snoyberg/conduit/blob/master/PROCESS.md>. -- -- Note that this is a very thin layer around the @Data.Streaming.Process@ module. In particular, it: --
conduit-extra.cabal view
@@ -1,5 +1,5 @@ Name: conduit-extra-Version: 1.1.13.3+Version: 1.1.14 Synopsis: Batteries included conduit: adapters for common libraries. Description: The conduit package itself maintains relative small dependencies. The purpose of this package is to collect commonly used utility functions wrapping other library dependencies, without depending on heavier-weight dependencies. The basic idea is that this package should only depend on haskell-platform packages and conduit.
test/Data/Conduit/BinarySpec.hs view
@@ -157,6 +157,22 @@ lbs' `shouldBe` lbs fromIntegral len `shouldBe` L.length lbs' + describe "sinkFileCautious" $ do+ it' "success" $ do+ runResourceT $ CB.sourceFile "conduit-extra.cabal" C.$$ CB.sinkFileCautious "tmp"+ bs1 <- S.readFile "conduit-extra.cabal"+ bs2 <- S.readFile "tmp"+ bs2 `shouldBe` bs1+ it' "failure" $ do+ let bs1 = "This is the original content"+ S.writeFile "tmp" bs1+ runResourceT+ ( (CB.sourceFile "conduit-extra.cabal" >> error "FIXME")+ C.$$ CB.sinkFileCautious "tmp")+ `shouldThrow` anyException+ bs2 <- S.readFile "tmp"+ bs2 `shouldBe` bs1+ describe "Data.Conduit.Binary.mapM_" $ do prop "telling works" $ \bytes -> let lbs = L.pack bytes