process-streaming 0.9.0.1 → 0.9.1.0
raw patch · 5 files changed
+60/−4 lines, 5 files
Files
- CHANGELOG +5/−0
- process-streaming.cabal +1/−1
- src/System/Process/Lens.hs +26/−0
- src/System/Process/Streaming.hs +27/−2
- src/System/Process/Streaming/Text.hs +1/−1
CHANGELOG view
@@ -1,3 +1,8 @@+0.9.1.0+-------+- Added executeInteractive and executeInteractiveFallibly+- Added envAt lens for tweaking the environment.+ 0.9.0.0 ------- - All Siphon functionality has been moved to new package pipes-transduce.
process-streaming.cabal view
@@ -1,5 +1,5 @@ name: process-streaming-version: 0.9.0.1+version: 0.9.1.0 license: BSD3 license-file: LICENSE data-files:
src/System/Process/Lens.hs view
@@ -5,6 +5,9 @@ -- These are provided as a convenience and aren't at all required to use the -- other modules of this package. --+-- For basic lens functionality with few dependencies, the @microlens@ package+-- is a good option.+-- ----------------------------------------------------------------------------- {-# LANGUAGE RankNTypes #-}@@ -16,6 +19,7 @@ , _RawCommand , _cwd , _env+ , envAt , std_streams , _std_in , _std_out@@ -79,6 +83,28 @@ _env f x = setEnv x <$> f (env x) where setEnv c env' = c { env = env' } +++{-| An improper lens to get and insert values in an association list. It+ assumes that there are no duplicate keys in the list.++-}+envAt :: (Eq k,Applicative f)+ => k + -> (Maybe v -> f (Maybe v)) + -> ([(k,v)] -> f [(k,v)])+envAt key f [] =+ let listize Nothing = []+ listize (Just i) = [(key,i)]+ in+ listize <$> f Nothing+envAt key f (entry@(k,v):entries)+ | key == k =+ let listize Nothing = entries+ listize (Just v') = (k,v') : entries+ in+ listize <$> f (Just v)+ | otherwise = (entry:) <$> envAt key f entries {-| A lens for the @(std_in,std_out,std_err)@ triplet.
src/System/Process/Streaming.hs view
@@ -27,6 +27,9 @@ -- * Execution execute , executeFallibly+ -- ** Unbuffered stdin+ , executeInteractive+ , executeInteractiveFallibly -- * CreateProcess helpers , piped -- * The Streams Applicative@@ -140,7 +143,12 @@ execute :: CreateProcess -> Streams Void a -> IO a execute cprocess pp = either absurd id <$> executeFallibly cprocess pp +{-| Like 'execute', but 'std_in' will be unbuffered if piped. +-}+executeInteractive :: CreateProcess -> Streams Void a -> IO a+executeInteractive cprocess pp = either absurd id <$> executeInteractiveFallibly cprocess pp+ {-| Like 'execute', but allows the handlers in the 'Streams' Applicative to interrupt the execution of the external process by returning a 'Left' value, in addition to throwing exceptions. This is sometimes more convenient: >>> executeFallibly (piped (shell "sleep infinity")) (foldOut (withFallibleCont (\_ -> pure (Left "oops"))))@@ -156,8 +164,25 @@ CreateProcess -> Streams e a -> IO (Either e a)-executeFallibly record (Streams streams) = mask $ \restore -> do+executeFallibly = executeFalliblyInternal (\_ -> return ())++{-| Like 'executeFallibly', but 'std_in' will be unbuffered if piped. ++-}+executeInteractiveFallibly :: + CreateProcess + -> Streams e a+ -> IO (Either e a)+executeInteractiveFallibly = executeFalliblyInternal (\h -> hSetBuffering h NoBuffering)++executeFalliblyInternal :: + (Handle -> IO ())+ -> CreateProcess + -> Streams e a+ -> IO (Either e a)+executeFalliblyInternal adapter record (Streams streams) = mask $ \restore -> do (mstdin,mstdout,mstderr,phandle) <- createProcess record+ forM_ mstdin adapter let (clientx,cleanupx) = case mstdin of Nothing -> (pure (),pure ()) Just handle -> (toHandle handle,hClose handle) @@ -391,7 +416,7 @@ {-| The type of handlers that write to piped @stdin@, consume piped @stdout@ and @stderr@, and work with the process exit code, eventually returning a value of- type @a@, except when an error @e@ interrups the execution.+ type @r@, except when an error @e@ interrups the execution. Example of a complex handler:
src/System/Process/Streaming/Text.hs view
@@ -63,7 +63,7 @@ stream. We can do this with 'System.Process.Streaming.foldOutErr' and the 'Pipes.Transduce.combined' function. 'combined' takes one 'Pipes.Transduce.Transducer' for @stdout@ and another- for @stderr@, that known how to decode each stream into text, then break+ for @stderr@, that know how to decode each stream into text, then break the text into lines. The resulting lines are consumed using a 'Fold1':