11{-# LANGUAGE BangPatterns #-}
22{-# LANGUAGE DeriveDataTypeable #-}
3+ {-# LANGUAGE FlexibleContexts #-}
34{-# LANGUAGE KindSignatures #-}
45{-# LANGUAGE RankNTypes #-}
56{-# LANGUAGE TemplateHaskell #-}
89-- | Reading from external processes.
910
1011module System.Process.Read
11- (readProcessStdout
12+ (readProcessStdoutLogStderr
13+ ,readProcessStdout
1214 ,tryProcessStdout
13- ,sinkProcessStderrStdout
15+ ,sinkProcessStdoutLogStderr
1416 ,sinkProcessStdout
17+ ,sinkProcessStderrStdout
1518 ,EnvOverride
1619 ,unEnvOverride
1720 ,mkEnvOverride
@@ -29,12 +32,14 @@ import Control.Applicative
2932import Control.Arrow ((***) , first )
3033import Control.Concurrent.Async (Concurrently (.. ))
3134import Control.Exception
32- import Control.Monad (join , liftM )
35+ import Control.Monad (join , liftM , void )
3336import Control.Monad.Catch (MonadThrow , throwM )
3437import Control.Monad.IO.Class (MonadIO , liftIO )
3538import Control.Monad.Logger (MonadLogger , logError )
39+ import Control.Monad.Trans.Control (MonadBaseControl ,liftBaseWith )
3640import qualified Data.ByteString as S
3741import Data.Conduit
42+ import qualified Data.Conduit.Combinators as CC
3843import qualified Data.Conduit.List as CL
3944import Data.Conduit.Process hiding (callProcess )
4045import Data.Foldable (forM_ )
@@ -163,6 +168,49 @@ readProcessStdout wd menv name args =
163168 sinkProcessStdout wd menv name args CL. consume >>=
164169 liftIO . evaluate . S. concat
165170
171+ -- | Produce a strict 'S.ByteString' from the stdout of a
172+ -- process. Throws a 'ProcessExitedUnsuccessfully' exception if the
173+ -- process fails. Logs process's stderr using @$logError@.
174+ readProcessStdoutLogStderr :: (MonadIO m ,MonadLogger m ,MonadBaseControl IO m )
175+ => Text
176+ -> Maybe (Path Abs Dir )
177+ -> EnvOverride
178+ -> String
179+ -> [String ]
180+ -> m S. ByteString
181+ readProcessStdoutLogStderr stderrPrefix wd menv name args = do
182+ stdout <- sinkProcessStdoutLogStderr stderrPrefix wd menv name args CL. consume
183+ liftIO (evaluate (S. concat stdout))
184+
185+ -- | Consume the stdout of a process feeding strict 'S.ByteString's to a consumer.
186+ -- Logs process's stderr using @$logError@.
187+ sinkProcessStdoutLogStderr :: (MonadIO m ,MonadLogger m ,MonadBaseControl IO m )
188+ => Text -- ^ Prefix for any logged stderr message
189+ -> Maybe (Path Abs Dir )
190+ -> EnvOverride
191+ -> String
192+ -> [String ]
193+ -> Sink S. ByteString IO a -- ^ Sink for stdout
194+ -> m a
195+ sinkProcessStdoutLogStderr stderrPrefix wd menv name args sinkStdout = do
196+ runInBase <- liftBaseWith $ \ run -> return (void . run)
197+ let logSink = CC. mapM_ (liftIO . runInBase . $ logError . T. append stderrPrefix)
198+ sinkStderr = CC. decodeUtf8 =$= CC. line logSink
199+ (_,stdout) <- sinkProcessStderrStdout wd menv name args sinkStderr sinkStdout
200+ return stdout
201+
202+ -- | Consume the stdout of a process feeding strict 'S.ByteString's to a consumer.
203+ sinkProcessStdout :: (MonadIO m )
204+ => Maybe (Path Abs Dir )
205+ -> EnvOverride
206+ -> String
207+ -> [String ]
208+ -> Sink S. ByteString IO a
209+ -> m a
210+ sinkProcessStdout wd menv name args sink = do
211+ (_,stdout) <- sinkProcessStderrStdout wd menv name args CL. sinkNull sink
212+ return stdout
213+
166214-- | Consume the stdout and stderr of a process feeding strict 'S.ByteString's to the consumers.
167215sinkProcessStderrStdout :: (MonadIO m )
168216 => Maybe (Path Abs Dir )
@@ -184,17 +232,6 @@ sinkProcessStderrStdout wd menv name args sinkStderr sinkStdout = do
184232 where asBSSource :: Source m S. ByteString -> Source m S. ByteString
185233 asBSSource = id
186234
187- -- | Consume the stdout of a process feeding strict 'S.ByteString's to a consumer.
188- sinkProcessStdout :: (MonadIO m )
189- => Maybe (Path Abs Dir )
190- -> EnvOverride
191- -> String
192- -> [String ]
193- -> Sink S. ByteString IO a
194- -> m a
195- sinkProcessStdout wd menv name args sink = do
196- (_,stdout) <- sinkProcessStderrStdout wd menv name args CL. sinkNull sink
197- return stdout
198235
199236-- | Perform pre-call-process tasks. Ensure the working directory exists and find the
200237-- executable path.
0 commit comments