Skip to content

Commit eddfdc2

Browse files
committed
System.Process.Read: add 'sinkProcessStdoutLogStderr' and 'readProcessStdoutLogStderr'
1 parent 0309780 commit eddfdc2

File tree

1 file changed

+51
-14
lines changed

1 file changed

+51
-14
lines changed

src/System/Process/Read.hs

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{-# LANGUAGE BangPatterns #-}
22
{-# LANGUAGE DeriveDataTypeable #-}
3+
{-# LANGUAGE FlexibleContexts #-}
34
{-# LANGUAGE KindSignatures #-}
45
{-# LANGUAGE RankNTypes #-}
56
{-# LANGUAGE TemplateHaskell #-}
@@ -8,10 +9,12 @@
89
-- | Reading from external processes.
910

1011
module 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
2932
import Control.Arrow ((***), first)
3033
import Control.Concurrent.Async (Concurrently (..))
3134
import Control.Exception
32-
import Control.Monad (join, liftM)
35+
import Control.Monad (join, liftM, void)
3336
import Control.Monad.Catch (MonadThrow, throwM)
3437
import Control.Monad.IO.Class (MonadIO, liftIO)
3538
import Control.Monad.Logger (MonadLogger, logError)
39+
import Control.Monad.Trans.Control (MonadBaseControl,liftBaseWith)
3640
import qualified Data.ByteString as S
3741
import Data.Conduit
42+
import qualified Data.Conduit.Combinators as CC
3843
import qualified Data.Conduit.List as CL
3944
import Data.Conduit.Process hiding (callProcess)
4045
import 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.
167215
sinkProcessStderrStdout :: (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

Comments
 (0)