conduit-extra 1.3.7 → 1.3.8
raw patch · 4 files changed
+25/−3 lines, 4 filesdep ~basePVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: base
API changes (from Hackage documentation)
- Data.Conduit.Attoparsec: conduitParser :: (AttoparsecInput a, MonadThrow m) => Parser a b -> ConduitT a (PositionRange, b) m ()
+ Data.Conduit.Attoparsec: conduitParser :: forall a (m :: Type -> Type) b. (AttoparsecInput a, MonadThrow m) => Parser a b -> ConduitT a (PositionRange, b) m ()
- Data.Conduit.Attoparsec: conduitParserEither :: (Monad m, AttoparsecInput a) => Parser a b -> ConduitT a (Either ParseError (PositionRange, b)) m ()
+ Data.Conduit.Attoparsec: conduitParserEither :: forall (m :: Type -> Type) a b. (Monad m, AttoparsecInput a) => Parser a b -> ConduitT a (Either ParseError (PositionRange, b)) m ()
- Data.Conduit.Attoparsec: sinkParser :: (AttoparsecInput a, MonadThrow m) => Parser a b -> ConduitT a o m b
+ Data.Conduit.Attoparsec: sinkParser :: forall a (m :: Type -> Type) b o. (AttoparsecInput a, MonadThrow m) => Parser a b -> ConduitT a o m b
- Data.Conduit.Attoparsec: sinkParserEither :: (AttoparsecInput a, Monad m) => Parser a b -> ConduitT a o m (Either ParseError b)
+ Data.Conduit.Attoparsec: sinkParserEither :: forall a (m :: Type -> Type) b o. (AttoparsecInput a, Monad m) => Parser a b -> ConduitT a o m (Either ParseError b)
- Data.Conduit.Binary: conduitFile :: MonadResource m => FilePath -> ConduitT ByteString ByteString m ()
+ Data.Conduit.Binary: conduitFile :: forall (m :: Type -> Type). MonadResource m => FilePath -> ConduitT ByteString ByteString m ()
- Data.Conduit.Binary: conduitHandle :: MonadIO m => Handle -> ConduitT ByteString ByteString m ()
+ Data.Conduit.Binary: conduitHandle :: forall (m :: Type -> Type). MonadIO m => Handle -> ConduitT ByteString ByteString m ()
- Data.Conduit.Binary: drop :: Monad m => Int -> ConduitT ByteString o m ()
+ Data.Conduit.Binary: drop :: forall (m :: Type -> Type) o. Monad m => Int -> ConduitT ByteString o m ()
- Data.Conduit.Binary: dropWhile :: Monad m => (Word8 -> Bool) -> ConduitT ByteString o m ()
+ Data.Conduit.Binary: dropWhile :: forall (m :: Type -> Type) o. Monad m => (Word8 -> Bool) -> ConduitT ByteString o m ()
- Data.Conduit.Binary: head :: Monad m => ConduitT ByteString o m (Maybe Word8)
+ Data.Conduit.Binary: head :: forall (m :: Type -> Type) o. Monad m => ConduitT ByteString o m (Maybe Word8)
- Data.Conduit.Binary: isolate :: Monad m => Int -> ConduitT ByteString ByteString m ()
+ Data.Conduit.Binary: isolate :: forall (m :: Type -> Type). Monad m => Int -> ConduitT ByteString ByteString m ()
- Data.Conduit.Binary: lines :: Monad m => ConduitT ByteString ByteString m ()
+ Data.Conduit.Binary: lines :: forall (m :: Type -> Type). Monad m => ConduitT ByteString ByteString m ()
- Data.Conduit.Binary: sinkCacheLength :: (MonadResource m1, MonadResource m2) => ConduitT ByteString o m1 (Word64, ConduitT i ByteString m2 ())
+ Data.Conduit.Binary: sinkCacheLength :: forall (m1 :: Type -> Type) (m2 :: Type -> Type) o i. (MonadResource m1, MonadResource m2) => ConduitT ByteString o m1 (Word64, ConduitT i ByteString m2 ())
- Data.Conduit.Binary: sinkLbs :: Monad m => ConduitT ByteString o m ByteString
+ Data.Conduit.Binary: sinkLbs :: forall (m :: Type -> Type) o. Monad m => ConduitT ByteString o m ByteString
- Data.Conduit.Binary: sinkStorable :: (Monad m, Storable a) => ConduitT ByteString o m (Maybe a)
+ Data.Conduit.Binary: sinkStorable :: forall (m :: Type -> Type) a o. (Monad m, Storable a) => ConduitT ByteString o m (Maybe a)
- Data.Conduit.Binary: sinkStorableEx :: (MonadThrow m, Storable a) => ConduitT ByteString o m a
+ Data.Conduit.Binary: sinkStorableEx :: forall (m :: Type -> Type) a o. (MonadThrow m, Storable a) => ConduitT ByteString o m a
- Data.Conduit.Binary: sourceFileRange :: MonadResource m => FilePath -> Maybe Integer -> Maybe Integer -> ConduitT i ByteString m ()
+ Data.Conduit.Binary: sourceFileRange :: forall (m :: Type -> Type) i. MonadResource m => FilePath -> Maybe Integer -> Maybe Integer -> ConduitT i ByteString m ()
- Data.Conduit.Binary: sourceHandleRange :: MonadIO m => Handle -> Maybe Integer -> Maybe Integer -> ConduitT i ByteString m ()
+ Data.Conduit.Binary: sourceHandleRange :: forall (m :: Type -> Type) i. MonadIO m => Handle -> Maybe Integer -> Maybe Integer -> ConduitT i ByteString m ()
- Data.Conduit.Binary: sourceHandleRangeWithBuffer :: MonadIO m => Handle -> Maybe Integer -> Maybe Integer -> Int -> ConduitT i ByteString m ()
+ Data.Conduit.Binary: sourceHandleRangeWithBuffer :: forall (m :: Type -> Type) i. MonadIO m => Handle -> Maybe Integer -> Maybe Integer -> Int -> ConduitT i ByteString m ()
- Data.Conduit.Binary: sourceLbs :: Monad m => ByteString -> ConduitT i ByteString m ()
+ Data.Conduit.Binary: sourceLbs :: forall (m :: Type -> Type) i. Monad m => ByteString -> ConduitT i ByteString m ()
- Data.Conduit.Binary: take :: Monad m => Int -> ConduitT ByteString o m ByteString
+ Data.Conduit.Binary: take :: forall (m :: Type -> Type) o. Monad m => Int -> ConduitT ByteString o m ByteString
- Data.Conduit.Binary: takeWhile :: Monad m => (Word8 -> Bool) -> ConduitT ByteString ByteString m ()
+ Data.Conduit.Binary: takeWhile :: forall (m :: Type -> Type). Monad m => (Word8 -> Bool) -> ConduitT ByteString ByteString m ()
- Data.Conduit.Foldl: sinkFold :: Monad m => (x -> a -> x) -> x -> (x -> b) -> ConduitT a o m b
+ Data.Conduit.Foldl: sinkFold :: forall (m :: Type -> Type) x a b o. Monad m => (x -> a -> x) -> x -> (x -> b) -> ConduitT a o m b
- Data.Conduit.Lazy: class Monad m => MonadActive m
+ Data.Conduit.Lazy: class Monad m => MonadActive (m :: Type -> Type)
- Data.Conduit.Lazy: lazyConsume :: forall m a. (MonadUnliftIO m, MonadActive m) => Source m a -> m [a]
+ Data.Conduit.Lazy: lazyConsume :: (MonadUnliftIO m, MonadActive m) => Source m a -> m [a]
- Data.Conduit.Network: appSink :: (HasReadWrite ad, MonadIO m) => ad -> ConduitT ByteString o m ()
+ Data.Conduit.Network: appSink :: forall ad (m :: Type -> Type) o. (HasReadWrite ad, MonadIO m) => ad -> ConduitT ByteString o m ()
- Data.Conduit.Network: appSource :: (HasReadWrite ad, MonadIO m) => ad -> ConduitT i ByteString m ()
+ Data.Conduit.Network: appSource :: forall ad (m :: Type -> Type) i. (HasReadWrite ad, MonadIO m) => ad -> ConduitT i ByteString m ()
- Data.Conduit.Network: data () => AppData
+ Data.Conduit.Network: data AppData
- Data.Conduit.Network: data () => ClientSettings
+ Data.Conduit.Network: data ClientSettings
- Data.Conduit.Network: data () => HostPreference
+ Data.Conduit.Network: data HostPreference
- Data.Conduit.Network: data () => ServerSettings
+ Data.Conduit.Network: data ServerSettings
- Data.Conduit.Network: sinkSocket :: MonadIO m => Socket -> ConduitT ByteString o m ()
+ Data.Conduit.Network: sinkSocket :: forall (m :: Type -> Type) o. MonadIO m => Socket -> ConduitT ByteString o m ()
- Data.Conduit.Network: sourceSocket :: MonadIO m => Socket -> ConduitT i ByteString m ()
+ Data.Conduit.Network: sourceSocket :: forall (m :: Type -> Type) i. MonadIO m => Socket -> ConduitT i ByteString m ()
- Data.Conduit.Network.UDP: data () => HostPreference
+ Data.Conduit.Network.UDP: data HostPreference
- Data.Conduit.Network.UDP: data () => Message
+ Data.Conduit.Network.UDP: data Message
- Data.Conduit.Network.UDP: sinkAllSocket :: MonadIO m => Socket -> ConduitT ByteString o m ()
+ Data.Conduit.Network.UDP: sinkAllSocket :: forall (m :: Type -> Type) o. MonadIO m => Socket -> ConduitT ByteString o m ()
- Data.Conduit.Network.UDP: sinkAllToSocket :: MonadIO m => Socket -> ConduitT Message o m ()
+ Data.Conduit.Network.UDP: sinkAllToSocket :: forall (m :: Type -> Type) o. MonadIO m => Socket -> ConduitT Message o m ()
- Data.Conduit.Network.UDP: sinkSocket :: MonadIO m => Socket -> ConduitT ByteString o m ()
+ Data.Conduit.Network.UDP: sinkSocket :: forall (m :: Type -> Type) o. MonadIO m => Socket -> ConduitT ByteString o m ()
- Data.Conduit.Network.UDP: sinkToSocket :: MonadIO m => Socket -> ConduitT Message o m ()
+ Data.Conduit.Network.UDP: sinkToSocket :: forall (m :: Type -> Type) o. MonadIO m => Socket -> ConduitT Message o m ()
- Data.Conduit.Network.UDP: sourceSocket :: MonadIO m => Socket -> Int -> ConduitT i Message m ()
+ Data.Conduit.Network.UDP: sourceSocket :: forall (m :: Type -> Type) i. MonadIO m => Socket -> Int -> ConduitT i Message m ()
- Data.Conduit.Network.Unix: appSink :: (HasReadWrite ad, MonadIO m) => ad -> ConduitT ByteString o m ()
+ Data.Conduit.Network.Unix: appSink :: forall ad (m :: Type -> Type) o. (HasReadWrite ad, MonadIO m) => ad -> ConduitT ByteString o m ()
- Data.Conduit.Network.Unix: appSource :: (HasReadWrite ad, MonadIO m) => ad -> ConduitT i ByteString m ()
+ Data.Conduit.Network.Unix: appSource :: forall ad (m :: Type -> Type) i. (HasReadWrite ad, MonadIO m) => ad -> ConduitT i ByteString m ()
- Data.Conduit.Network.Unix: data () => AppDataUnix
+ Data.Conduit.Network.Unix: data AppDataUnix
- Data.Conduit.Network.Unix: data () => ClientSettingsUnix
+ Data.Conduit.Network.Unix: data ClientSettingsUnix
- Data.Conduit.Network.Unix: data () => ServerSettingsUnix
+ Data.Conduit.Network.Unix: data ServerSettingsUnix
- Data.Conduit.Network.Unix: sinkSocket :: MonadIO m => Socket -> ConduitT ByteString o m ()
+ Data.Conduit.Network.Unix: sinkSocket :: forall (m :: Type -> Type) o. MonadIO m => Socket -> ConduitT ByteString o m ()
- Data.Conduit.Network.Unix: sourceSocket :: MonadIO m => Socket -> ConduitT i ByteString m ()
+ Data.Conduit.Network.Unix: sourceSocket :: forall (m :: Type -> Type) i. MonadIO m => Socket -> ConduitT i ByteString m ()
- Data.Conduit.Process: BuilderInput :: ConduitM Builder o m r -> BuilderInput o m r
+ Data.Conduit.Process: BuilderInput :: ConduitM Builder o m r -> BuilderInput o (m :: Type -> Type) r
- Data.Conduit.Process: FlushInput :: ConduitM (Flush ByteString) o m r -> FlushInput o m r
+ Data.Conduit.Process: FlushInput :: ConduitM (Flush ByteString) o m r -> FlushInput o (m :: Type -> Type) r
- Data.Conduit.Process: newtype BuilderInput o m r
+ Data.Conduit.Process: newtype BuilderInput o (m :: Type -> Type) r
- Data.Conduit.Process: newtype FlushInput o m r
+ Data.Conduit.Process: newtype FlushInput o (m :: Type -> Type) r
- Data.Conduit.Process.Typed: createSink :: MonadIO m => StreamSpec 'STInput (ConduitM ByteString o m ())
+ Data.Conduit.Process.Typed: createSink :: forall (m :: Type -> Type) o. MonadIO m => StreamSpec 'STInput (ConduitM ByteString o m ())
- Data.Conduit.Process.Typed: createSinkClose :: MonadIO m => StreamSpec 'STInput (ConduitM ByteString o m ())
+ Data.Conduit.Process.Typed: createSinkClose :: forall (m :: Type -> Type) o. MonadIO m => StreamSpec 'STInput (ConduitM ByteString o m ())
- Data.Conduit.Process.Typed: createSource :: MonadIO m => StreamSpec 'STOutput (ConduitM i ByteString m ())
+ Data.Conduit.Process.Typed: createSource :: forall (m :: Type -> Type) i. MonadIO m => StreamSpec 'STOutput (ConduitM i ByteString m ())
- Data.Conduit.Text: decode :: MonadThrow m => Codec -> ConduitT ByteString Text m ()
+ Data.Conduit.Text: decode :: forall (m :: Type -> Type). MonadThrow m => Codec -> ConduitT ByteString Text m ()
- Data.Conduit.Text: detectUtf :: MonadThrow m => ConduitT ByteString Text m ()
+ Data.Conduit.Text: detectUtf :: forall (m :: Type -> Type). MonadThrow m => ConduitT ByteString Text m ()
- Data.Conduit.Text: drop :: Monad m => Int -> ConduitT Text o m ()
+ Data.Conduit.Text: drop :: forall (m :: Type -> Type) o. Monad m => Int -> ConduitT Text o m ()
- Data.Conduit.Text: dropWhile :: Monad m => (Char -> Bool) -> ConduitT Text o m ()
+ Data.Conduit.Text: dropWhile :: forall (m :: Type -> Type) o. Monad m => (Char -> Bool) -> ConduitT Text o m ()
- Data.Conduit.Text: encode :: MonadThrow m => Codec -> ConduitT Text ByteString m ()
+ Data.Conduit.Text: encode :: forall (m :: Type -> Type). MonadThrow m => Codec -> ConduitT Text ByteString m ()
- Data.Conduit.Text: foldLines :: Monad m => (a -> ConduitM Text o m a) -> a -> ConduitT Text o m a
+ Data.Conduit.Text: foldLines :: forall (m :: Type -> Type) a o. Monad m => (a -> ConduitM Text o m a) -> a -> ConduitT Text o m a
- Data.Conduit.Text: lines :: Monad m => ConduitT Text Text m ()
+ Data.Conduit.Text: lines :: forall (m :: Type -> Type). Monad m => ConduitT Text Text m ()
- Data.Conduit.Text: linesBounded :: MonadThrow m => Int -> ConduitT Text Text m ()
+ Data.Conduit.Text: linesBounded :: forall (m :: Type -> Type). MonadThrow m => Int -> ConduitT Text Text m ()
- Data.Conduit.Text: take :: Monad m => Int -> ConduitT Text Text m ()
+ Data.Conduit.Text: take :: forall (m :: Type -> Type). Monad m => Int -> ConduitT Text Text m ()
- Data.Conduit.Text: takeWhile :: Monad m => (Char -> Bool) -> ConduitT Text Text m ()
+ Data.Conduit.Text: takeWhile :: forall (m :: Type -> Type). Monad m => (Char -> Bool) -> ConduitT Text Text m ()
- Data.Conduit.Text: withLine :: Monad m => ConduitT Text Void m a -> ConduitT Text o m (Maybe a)
+ Data.Conduit.Text: withLine :: forall (m :: Type -> Type) a o. Monad m => ConduitT Text Void m a -> ConduitT Text o m (Maybe a)
- Data.Conduit.Zlib: compress :: (PrimMonad m, MonadThrow m) => Int -> WindowBits -> ConduitT ByteString ByteString m ()
+ Data.Conduit.Zlib: compress :: forall (m :: Type -> Type). (PrimMonad m, MonadThrow m) => Int -> WindowBits -> ConduitT ByteString ByteString m ()
- Data.Conduit.Zlib: compressFlush :: (PrimMonad m, MonadThrow m) => Int -> WindowBits -> ConduitT (Flush ByteString) (Flush ByteString) m ()
+ Data.Conduit.Zlib: compressFlush :: forall (m :: Type -> Type). (PrimMonad m, MonadThrow m) => Int -> WindowBits -> ConduitT (Flush ByteString) (Flush ByteString) m ()
- Data.Conduit.Zlib: decompress :: (PrimMonad m, MonadThrow m) => WindowBits -> ConduitT ByteString ByteString m ()
+ Data.Conduit.Zlib: decompress :: forall (m :: Type -> Type). (PrimMonad m, MonadThrow m) => WindowBits -> ConduitT ByteString ByteString m ()
- Data.Conduit.Zlib: decompressFlush :: (PrimMonad m, MonadThrow m) => WindowBits -> ConduitT (Flush ByteString) (Flush ByteString) m ()
+ Data.Conduit.Zlib: decompressFlush :: forall (m :: Type -> Type). (PrimMonad m, MonadThrow m) => WindowBits -> ConduitT (Flush ByteString) (Flush ByteString) m ()
- Data.Conduit.Zlib: gzip :: (MonadThrow m, PrimMonad m) => ConduitT ByteString ByteString m ()
+ Data.Conduit.Zlib: gzip :: forall (m :: Type -> Type). (MonadThrow m, PrimMonad m) => ConduitT ByteString ByteString m ()
- Data.Conduit.Zlib: multiple :: Monad m => ConduitT ByteString a m () -> ConduitT ByteString a m ()
+ Data.Conduit.Zlib: multiple :: forall (m :: Type -> Type) a. Monad m => ConduitT ByteString a m () -> ConduitT ByteString a m ()
- Data.Conduit.Zlib: newtype () => WindowBits
+ Data.Conduit.Zlib: newtype WindowBits
- Data.Conduit.Zlib: ungzip :: (PrimMonad m, MonadThrow m) => ConduitT ByteString ByteString m ()
+ Data.Conduit.Zlib: ungzip :: forall (m :: Type -> Type). (PrimMonad m, MonadThrow m) => ConduitT ByteString ByteString m ()
Files
- ChangeLog.md +4/−0
- Data/Conduit/Process.hs +11/−2
- conduit-extra.cabal +1/−1
- test/Data/Conduit/ProcessSpec.hs +9/−0
ChangeLog.md view
@@ -1,5 +1,9 @@ # ChangeLog for conduit-extra +## 1.3.8++* Gracefully handle when a subprocess started using `Data.Conduit.Process.sourceProcessWithStreams` closes its stdin. Fixes [#523](https://github.com/snoyberg/conduit/issues/523)+ ## 1.3.7 * Allow Data.Conduit.Network.Unix on Windows [#518](https://github.com/snoyberg/conduit/pull/518)
Data/Conduit/Process.hs view
@@ -39,7 +39,8 @@ import Data.ByteString (ByteString) import Data.ByteString.Builder (Builder) import Control.Concurrent.Async (runConcurrently, Concurrently(..))-import Control.Exception (onException, throwIO, finally, bracket)+import Control.Exception (onException, throwIO, finally, bracket, catch)+import System.IO.Error (ioeGetErrorType, isResourceVanishedErrorType) #if (__GLASGOW_HASKELL__ < 710) import Control.Applicative ((<$>), (<*>)) #endif@@ -143,16 +144,24 @@ , (sourceStdout, closeStdout) , (sourceStderr, closeStderr) , sph) <- streamingProcess cp+ let safeSinkStdin = sinkStdin `catchC` ignoreStdinClosed+ safeCloseStdin = closeStdin `catch` ignoreStdinClosed (_, resStdout, resStderr) <- runConcurrently ( (,,)- <$> Concurrently ((unliftIO u $ runConduit $ producerStdin .| sinkStdin) `finally` closeStdin)+ <$> Concurrently ((unliftIO u $ runConduit $ producerStdin .| safeSinkStdin) `finally` safeCloseStdin) <*> Concurrently (unliftIO u $ runConduit $ sourceStdout .| consumerStdout) <*> Concurrently (unliftIO u $ runConduit $ sourceStderr .| consumerStderr)) `finally` (closeStdout >> closeStderr) `onException` terminateStreamingProcess sph ec <- waitForStreamingProcess sph return (ec, resStdout, resStderr)+ where+ ignoreStdinClosed :: forall m. (MonadIO m) => IOError -> m ()+ ignoreStdinClosed e =+ if isResourceVanishedErrorType (ioeGetErrorType e)+ then pure ()+ else liftIO (throwIO e) -- | Like @sourceProcessWithStreams@ but providing the command to be run as -- a @String@.
conduit-extra.cabal view
@@ -1,6 +1,6 @@ Cabal-version: >=1.10 Name: conduit-extra-Version: 1.3.7+Version: 1.3.8 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/ProcessSpec.hs view
@@ -5,6 +5,7 @@ import Test.Hspec import Test.Hspec.QuickCheck (prop) import Data.Conduit+import qualified Data.Conduit.Combinators as CC import qualified Data.Conduit.List as CL import Data.Conduit.Process import Control.Concurrent.Async (concurrently)@@ -77,6 +78,14 @@ CL.consume -- stdout CL.consume -- stderr `shouldReturn` (ExitSuccess, [mystr], [])+ it "gracefully handles closed stdin" $ do+ let blob = L.iterate (+1) 0+ blobHead = L.toStrict $ L.take 10000 blob+ sourceCmdWithStreams "head -c 10000"+ (CC.sourceLazy blob)+ (L.toStrict <$> CC.sinkLazy) -- stdout+ CL.consume -- stderr+ `shouldReturn` (ExitSuccess, blobHead, []) #endif it "blocking vs non-blocking" $ do (ClosedStream, ClosedStream, ClosedStream, cph) <- streamingProcess (shell "sleep 1")