typed-process 0.2.6.0 → 0.2.6.1
raw patch · 4 files changed
+124/−39 lines, 4 filesdep ~base
Dependency ranges changed: base
Files
- ChangeLog.md +5/−1
- README.md +25/−24
- src/System/Process/Typed.hs +89/−7
- typed-process.cabal +5/−7
ChangeLog.md view
@@ -1,6 +1,10 @@ # ChangeLog for typed-process -## Unreleased+## 0.2.6.1++* Doc improvements++## 0.2.6.0 * The cleanup thread applies an `unmask` to the actions which wait for a process to exit, allowing the action to be interruptible.
README.md view
@@ -1,6 +1,6 @@ ## typed-process -[](https://travis-ci.org/fpco/typed-process) [](https://ci.appveyor.com/project/snoyberg/typed-process/branch/master)+[](https://github.com/fpco/typed-process/actions/workflows/tests.yml) API level documentation (Haddocks) may be [found on Stackage](https://www.stackage.org/package/typed-process).@@ -29,7 +29,7 @@ ```haskell #!/usr/bin/env stack--- stack --resolver lts-12.21 script+-- stack --resolver lts-16.27 script {-# LANGUAGE OverloadedStrings #-} import System.IO (hPutStr, hClose) import System.Process.Typed@@ -60,7 +60,7 @@ let catConfig = setStdin createPipe $ setStdout byteStringOutput $ proc "cat" ["/etc/hosts", "-", "/etc/group"]- withProcess_ catConfig $ \p -> do+ withProcessWait_ catConfig $ \p -> do hPutStr (getStdin p) "\n\nHELLO\n" hPutStr (getStdin p) "WORLD\n\n\n" hClose (getStdin p)@@ -85,14 +85,15 @@ ```haskell #!/usr/bin/env stack--- stack --resolver lts-12.21 script+-- stack --resolver lts-16.27 script {-# LANGUAGE OverloadedStrings #-} import System.Process.Typed main :: IO () main = do let dateConfig :: ProcessConfig () () ()- dateConfig = "date"+ dateConfig = proc "date" []+ -- alternatively: `shell "date"` or just "date" process <- startProcess dateConfig exitCode <- waitExitCode (process :: Process () () ())@@ -108,17 +109,17 @@ parameters in the next section.) Instead of explicitly dealing with `startProcess` and `stopProcess`,-it's recommended to instead use `withProcess`, which uses the bracket+it's recommended to instead use `withProcessWait`, which uses the bracket pattern and is exception safe: ```haskell #!/usr/bin/env stack--- stack --resolver lts-12.21 script+-- stack --resolver lts-16.27 script {-# LANGUAGE OverloadedStrings #-} import System.Process.Typed main :: IO ()-main = withProcess "date" $ \process -> do+main = withProcessWait "date" $ \process -> do exitCode <- waitExitCode (process :: Process () () ()) print exitCode ```@@ -129,7 +130,7 @@ ```haskell #!/usr/bin/env stack--- stack --resolver lts-12.21 script+-- stack --resolver lts-16.27 script {-# LANGUAGE OverloadedStrings #-} import System.Process.Typed @@ -157,7 +158,7 @@ ```haskell #!/usr/bin/env stack--- stack --resolver lts-12.21 script+-- stack --resolver lts-16.27 script {-# LANGUAGE OverloadedStrings #-} import System.Process.Typed @@ -189,7 +190,7 @@ ```haskell #!/usr/bin/env stack--- stack --resolver lts-12.21 script+-- stack --resolver lts-16.27 script {-# LANGUAGE OverloadedStrings #-} import System.Process.Typed @@ -220,7 +221,7 @@ ```haskell #!/usr/bin/env stack--- stack --resolver lts-12.21 script+-- stack --resolver lts-16.27 script {-# LANGUAGE OverloadedStrings #-} import System.Process.Typed @@ -234,7 +235,7 @@ ```haskell #!/usr/bin/env stack--- stack --resolver lts-12.21 script+-- stack --resolver lts-16.27 script {-# LANGUAGE OverloadedStrings #-} import System.Process.Typed @@ -247,12 +248,12 @@ ```haskell #!/usr/bin/env stack--- stack --resolver lts-12.21 script+-- stack --resolver lts-16.27 script {-# LANGUAGE OverloadedStrings #-} import System.Process.Typed main :: IO ()-main = withProcess "false" checkExitCode+main = withProcessWait "false" checkExitCode ``` ## Reading from a process@@ -265,7 +266,7 @@ ```haskell #!/usr/bin/env stack--- stack --resolver lts-12.21 script+-- stack --resolver lts-16.27 script {-# LANGUAGE OverloadedStrings #-} import System.Process.Typed import System.Exit (ExitCode)@@ -291,7 +292,7 @@ ```haskell #!/usr/bin/env stack--- stack --resolver lts-12.21 script+-- stack --resolver lts-16.27 script {-# LANGUAGE OverloadedStrings #-} import System.Process.Typed import Data.ByteString.Lazy (ByteString)@@ -317,7 +318,7 @@ ```haskell #!/usr/bin/env stack--- stack --resolver lts-12.21 script+-- stack --resolver lts-16.27 script {-# LANGUAGE OverloadedStrings #-} import System.Process.Typed import UnliftIO.Temporary (withSystemTempFile)@@ -341,7 +342,7 @@ ```haskell #!/usr/bin/env stack--- stack --resolver lts-12.21 script+-- stack --resolver lts-16.27 script {-# LANGUAGE OverloadedStrings #-} import System.Process.Typed import System.IO (hClose)@@ -371,7 +372,7 @@ ```haskell #!/usr/bin/env stack--- stack --resolver lts-12.21 script+-- stack --resolver lts-16.27 script {-# LANGUAGE OverloadedStrings #-} import System.Process.Typed @@ -383,7 +384,7 @@ ```haskell #!/usr/bin/env stack--- stack --resolver lts-12.21 script+-- stack --resolver lts-16.27 script {-# LANGUAGE OverloadedStrings #-} import System.Process.Typed @@ -396,7 +397,7 @@ ```haskell #!/usr/bin/env stack--- stack --resolver lts-12.21 script+-- stack --resolver lts-16.27 script {-# LANGUAGE OverloadedStrings #-} import System.Process.Typed import System.IO@@ -422,7 +423,7 @@ ```haskell #!/usr/bin/env stack--- stack --resolver lts-12.21 script+-- stack --resolver lts-16.27 script {-# LANGUAGE OverloadedStrings #-} import System.Process.Typed import System.IO@@ -456,7 +457,7 @@ ```haskell #!/usr/bin/env stack--- stack --resolver lts-12.21 script+-- stack --resolver lts-16.27 script {-# LANGUAGE OverloadedStrings #-} import System.Process.Typed
src/System/Process/Typed.hs view
@@ -6,7 +6,18 @@ {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-}--- | Please see the README.md file for examples of using this API.+-- | The simplest way to get started with this API is to turn on+-- @OverloadedStrings@ and call 'runProcess'. The following will+-- write the contents of @/home@ to @stdout@ and then print the exit+-- code (on a UNIX system).+--+-- @+-- {-\# LANGUAGE OverloadedStrings \#-}+--+-- runProcess "ls -l /home" >>= print+-- @+--+-- Please see the README.md file for more examples of using this API. module System.Process.Typed ( -- * Types ProcessConfig@@ -43,7 +54,7 @@ #endif -- * Stream specs- , mkStreamSpec+ -- ** Built-in stream specs , inherit , nullStream , closed@@ -53,6 +64,9 @@ , useHandleOpen , useHandleClose + -- ** Create your own stream spec+ , mkStreamSpec+ -- * Launch a process , startProcess , stopProcess@@ -210,8 +224,20 @@ data StreamType = STInput | STOutput -- | A specification for how to create one of the three standard child--- streams. See examples below.+-- streams, @stdin@, @stdout@ and @stderr@. A 'StreamSpec' can be+-- thought of as containing --+-- 1. A type safe version of 'P.StdStream' from "System.Process".+-- This determines whether the stream should be inherited from the+-- parent process, piped to or from a 'Handle', etc.+--+-- 2. A means of accessing the stream as a value of type @a@+--+-- 3. A cleanup action which will be run on the stream once the+-- process terminates+--+-- See examples below.+-- -- @since 0.1.0.0 data StreamSpec (streamType :: StreamType) a = StreamSpec { ssStream :: !(forall b. (P.StdStream -> IO b) -> IO b)@@ -311,7 +337,9 @@ -- -- @since 0.1.0.0 setStdin :: StreamSpec 'STInput stdin+ -- ^ -> ProcessConfig stdin0 stdout stderr+ -- ^ -> ProcessConfig stdin stdout stderr setStdin spec pc = pc { pcStdin = spec } @@ -321,7 +349,9 @@ -- -- @since 0.1.0.0 setStdout :: StreamSpec 'STOutput stdout+ -- ^ -> ProcessConfig stdin stdout0 stderr+ -- ^ -> ProcessConfig stdin stdout stderr setStdout spec pc = pc { pcStdout = spec } @@ -331,7 +361,9 @@ -- -- @since 0.1.0.0 setStderr :: StreamSpec 'STOutput stderr+ -- ^ -> ProcessConfig stdin stdout stderr0+ -- ^ -> ProcessConfig stdin stdout stderr setStderr spec pc = pc { pcStderr = spec } @@ -341,7 +373,9 @@ -- -- @since 0.1.0.0 setWorkingDir :: FilePath+ -- ^ -> ProcessConfig stdin stdout stderr+ -- ^ -> ProcessConfig stdin stdout stderr setWorkingDir dir pc = pc { pcWorkingDir = Just dir } @@ -350,6 +384,7 @@ -- @since 0.2.2.0 setWorkingDirInherit :: ProcessConfig stdin stdout stderr+ -- ^ -> ProcessConfig stdin stdout stderr setWorkingDirInherit pc = pc { pcWorkingDir = Nothing } @@ -359,7 +394,9 @@ -- -- @since 0.1.0.0 setEnv :: [(String, String)]+ -- ^ -> ProcessConfig stdin stdout stderr+ -- ^ -> ProcessConfig stdin stdout stderr setEnv env pc = pc { pcEnv = Just env } @@ -368,6 +405,7 @@ -- @since 0.2.2.0 setEnvInherit :: ProcessConfig stdin stdout stderr+ -- ^ -> ProcessConfig stdin stdout stderr setEnvInherit pc = pc { pcEnv = Nothing } @@ -379,7 +417,9 @@ -- @since 0.1.0.0 setCloseFds :: Bool+ -- ^ -> ProcessConfig stdin stdout stderr+ -- ^ -> ProcessConfig stdin stdout stderr setCloseFds x pc = pc { pcCloseFds = x } @@ -390,7 +430,9 @@ -- @since 0.1.0.0 setCreateGroup :: Bool+ -- ^ -> ProcessConfig stdin stdout stderr+ -- ^ -> ProcessConfig stdin stdout stderr setCreateGroup x pc = pc { pcCreateGroup = x } @@ -402,7 +444,9 @@ -- @since 0.1.0.0 setDelegateCtlc :: Bool+ -- ^ -> ProcessConfig stdin stdout stderr+ -- ^ -> ProcessConfig stdin stdout stderr setDelegateCtlc x pc = pc { pcDelegateCtlc = x } @@ -415,7 +459,9 @@ -- @since 0.1.0.0 setDetachConsole :: Bool+ -- ^ -> ProcessConfig stdin stdout stderr+ -- ^ -> ProcessConfig stdin stdout stderr setDetachConsole x pc = pc { pcDetachConsole = x } @@ -426,7 +472,9 @@ -- @since 0.1.0.0 setCreateNewConsole :: Bool+ -- ^ -> ProcessConfig stdin stdout stderr+ -- ^ -> ProcessConfig stdin stdout stderr setCreateNewConsole x pc = pc { pcCreateNewConsole = x } @@ -438,7 +486,9 @@ -- @since 0.1.0.0 setNewSession :: Bool+ -- ^ -> ProcessConfig stdin stdout stderr+ -- ^ -> ProcessConfig stdin stdout stderr setNewSession x pc = pc { pcNewSession = x } #endif@@ -452,7 +502,9 @@ -- @since 0.1.0.0 setChildGroup :: GroupID+ -- ^ -> ProcessConfig stdin stdout stderr+ -- ^ -> ProcessConfig stdin stdout stderr setChildGroup x pc = pc { pcChildGroup = Just x } @@ -461,6 +513,7 @@ -- @since 0.2.2.0 setChildGroupInherit :: ProcessConfig stdin stdout stderr+ -- ^ -> ProcessConfig stdin stdout stderr setChildGroupInherit pc = pc { pcChildGroup = Nothing } @@ -472,7 +525,9 @@ -- @since 0.1.0.0 setChildUser :: UserID+ -- ^ -> ProcessConfig stdin stdout stderr+ -- ^ -> ProcessConfig stdin stdout stderr setChildUser x pc = pc { pcChildUser = Just x } @@ -481,6 +536,7 @@ -- @since 0.2.2.0 setChildUserInherit :: ProcessConfig stdin stdout stderr+ -- ^ -> ProcessConfig stdin stdout stderr setChildUserInherit pc = pc { pcChildUser = Nothing } #endif@@ -489,15 +545,18 @@ -- helper function. This function: -- -- * Takes as input the raw @Maybe Handle@ returned by the--- 'P.createProcess' function. This will be determined by the--- 'P.StdStream' argument.+-- 'P.createProcess' function. The handle will be @Just@ 'Handle' if the+-- 'P.StdStream' argument is 'P.CreatePipe' and @Nothing@ otherwise.+-- See 'P.createProcess' for more details. -- -- * Returns the actual stream value @a@, as well as a cleanup--- * function to be run when calling 'stopProcess'.+-- function to be run when calling 'stopProcess'. -- -- @since 0.1.0.0 mkStreamSpec :: P.StdStream+ -- ^ -> (ProcessConfig () () () -> Maybe Handle -> IO (a, IO ()))+ -- ^ -> StreamSpec streamType a mkStreamSpec ss f = mkManagedStreamSpec ($ ss) f @@ -505,7 +564,9 @@ -- 'P.StdStream' and a helper function. This function is the same as -- the helper in 'mkStreamSpec' mkManagedStreamSpec :: (forall b. (P.StdStream -> IO b) -> IO b)+ -- ^ -> (ProcessConfig () () () -> Maybe Handle -> IO (a, IO ()))+ -- ^ -> StreamSpec streamType a mkManagedStreamSpec ss f = StreamSpec ss (\pc mh -> Cleanup (f pc mh)) @@ -621,13 +682,14 @@ useHandleClose h = mkStreamSpec (P.UseHandle h) $ \_ Nothing -> return ((), hClose h) -- | Launch a process based on the given 'ProcessConfig'. You should--- ensure that you close 'stopProcess' on the result. It's usually+-- ensure that you call 'stopProcess' on the result. It's usually -- better to use one of the functions in this module which ensures -- 'stopProcess' is called, such as 'withProcess'. -- -- @since 0.1.0.0 startProcess :: MonadIO m => ProcessConfig stdin stdout stderr+ -- ^ -> m (Process stdin stdout stderr) startProcess pConfig'@ProcessConfig {..} = liftIO $ do ssStream pcStdin $ \realStdin ->@@ -775,7 +837,9 @@ -- @since 0.2.5.0 withProcessWait :: (MonadUnliftIO m) => ProcessConfig stdin stdout stderr+ -- ^ -> (Process stdin stdout stderr -> m a)+ -- ^ -> m a withProcessWait config f = bracket@@ -798,7 +862,9 @@ -- @since 0.2.5.0 withProcessTerm_ :: (MonadUnliftIO m) => ProcessConfig stdin stdout stderr+ -- ^ -> (Process stdin stdout stderr -> m a)+ -- ^ -> m a withProcessTerm_ config = bracket (startProcess config)@@ -809,7 +875,9 @@ -- @since 0.2.5.0 withProcessWait_ :: (MonadUnliftIO m) => ProcessConfig stdin stdout stderr+ -- ^ -> (Process stdin stdout stderr -> m a)+ -- ^ -> m a withProcessWait_ config f = bracket (startProcess config)@@ -836,6 +904,7 @@ -- @since 0.1.0.0 readProcess :: MonadIO m => ProcessConfig stdin stdoutIgnored stderrIgnored+ -- ^ -> m (ExitCode, L.ByteString, L.ByteString) readProcess pc = liftIO $ withProcess pc' $ \p -> atomically $ (,,)@@ -854,6 +923,7 @@ -- @since 0.1.0.0 readProcess_ :: MonadIO m => ProcessConfig stdin stdoutIgnored stderrIgnored+ -- ^ -> m (L.ByteString, L.ByteString) readProcess_ pc = liftIO $ withProcess pc' $ \p -> atomically $ do@@ -874,6 +944,7 @@ readProcessStdout :: MonadIO m => ProcessConfig stdin stdoutIgnored stderr+ -- ^ -> m (ExitCode, L.ByteString) readProcessStdout pc = liftIO $ withProcess pc' $ \p -> atomically $ (,)@@ -891,6 +962,7 @@ readProcessStdout_ :: MonadIO m => ProcessConfig stdin stdoutIgnored stderr+ -- ^ -> m L.ByteString readProcessStdout_ pc = liftIO $ withProcess pc' $ \p -> atomically $ do@@ -909,6 +981,7 @@ readProcessStderr :: MonadIO m => ProcessConfig stdin stdout stderrIgnored+ -- ^ -> m (ExitCode, L.ByteString) readProcessStderr pc = liftIO $ withProcess pc' $ \p -> atomically $ (,)@@ -926,6 +999,7 @@ readProcessStderr_ :: MonadIO m => ProcessConfig stdin stdout stderrIgnored+ -- ^ -> m L.ByteString readProcessStderr_ pc = liftIO $ withProcess pc' $ \p -> atomically $ do@@ -939,7 +1013,9 @@ withProcessInterleave :: (MonadUnliftIO m) => ProcessConfig stdin stdoutIgnored stderrIgnored+ -- ^ -> (Process stdin (STM L.ByteString) () -> m a)+ -- ^ -> m a withProcessInterleave pc inner = -- Create a pipe to be shared for both stdout and stderr@@ -965,6 +1041,7 @@ readProcessInterleaved :: MonadIO m => ProcessConfig stdin stdoutIgnored stderrIgnored+ -- ^ -> m (ExitCode, L.ByteString) readProcessInterleaved pc = liftIO $@@ -982,7 +1059,9 @@ readProcessInterleaved_ :: MonadIO m => ProcessConfig stdin stdoutIgnored stderrIgnored+ -- ^ -> m L.ByteString+ -- ^ readProcessInterleaved_ pc = liftIO $ withProcessInterleave pc $ \p -> atomically $ do@@ -998,7 +1077,9 @@ -- @since 0.1.0.0 runProcess :: MonadIO m => ProcessConfig stdin stdout stderr+ -- ^ -> m ExitCode+ -- ^ runProcess pc = liftIO $ withProcess pc waitExitCode -- | Same as 'runProcess', but instead of returning the@@ -1007,6 +1088,7 @@ -- @since 0.1.0.0 runProcess_ :: MonadIO m => ProcessConfig stdin stdout stderr+ -- ^ -> m () runProcess_ pc = liftIO $ withProcess pc checkExitCode
typed-process.cabal view
@@ -1,13 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.31.2.+-- This file has been generated from package.yaml by hpack version 0.34.4. -- -- see: https://github.com/sol/hpack------ hash: f8fdbd0397d67fa0c8d6c96e3e95d3d6eb56d94fc13f0350fc60ff855d44d671 name: typed-process-version: 0.2.6.0+version: 0.2.6.1 synopsis: Run external processes, with strong typing of streams description: Please see the tutorial at <https://haskell-lang.org/library/typed-process> category: System@@ -36,7 +34,7 @@ src build-depends: async- , base >=4.8 && <5+ , base >=4.12 && <5 , bytestring , process >=1.2 , stm@@ -57,7 +55,7 @@ ghc-options: -threaded -rtsopts -with-rtsopts=-N build-depends: async- , base >=4.8 && <5+ , base >=4.12 && <5 , base64-bytestring , bytestring , hspec@@ -79,7 +77,7 @@ test build-depends: async- , base >=4.8 && <5+ , base >=4.12 && <5 , base64-bytestring , bytestring , hspec