process-conduit 0.5.0.5 → 1.2.0.1
raw patch · 5 files changed
Files
- Data/Conduit/Process.hs +0/−99
- Data/Conduit/ProcessOld.hs +101/−0
- System/Process/QQ.hs +3/−2
- process-conduit.cabal +15/−13
- test.hs +2/−1
− Data/Conduit/Process.hs
@@ -1,99 +0,0 @@-{-# LANGUAGE FlexibleContexts, OverloadedStrings, BangPatterns, RankNTypes #-} -module Data.Conduit.Process ( - -- * Run process - sourceProcess, - conduitProcess, - - -- * Run shell command - sourceCmd, - conduitCmd, - - -- * Convenience re-exports - shell, - proc, - CreateProcess(..), - CmdSpec(..), - StdStream(..), - ProcessHandle, - ) where - -import qualified Control.Exception as E -import Control.Monad -import Control.Monad.Trans -import Control.Monad.Trans.Loop -import qualified Data.ByteString as S -import Data.Conduit -import qualified Data.Conduit.List as CL -import Data.Maybe -import System.Exit (ExitCode(..)) -import System.IO -import System.Process - -bufSize :: Int -bufSize = 64 * 1024 - --- | Conduit of process -conduitProcess - :: MonadResource m - => CreateProcess - -> GConduit S.ByteString m S.ByteString -conduitProcess cp = bracketP createp closep $ \(Just cin, Just cout, _, ph) -> do - end <- repeatLoopT $ do - -- if process's outputs are available, then yields them. - repeatLoopT $ do - b <- liftIO $ hReady' cout - when (not b) exit - out <- liftIO $ S.hGetSome cout bufSize - void $ lift . lift $ yield out - - -- if process exited, then exit - end <- liftIO $ getProcessExitCode ph - when (isJust end) $ exitWith end - - -- if upper stream ended, then exit - inp <- lift await - when (isNothing inp) $ exitWith Nothing - - -- put input to process - liftIO $ S.hPut cin $ fromJust inp - liftIO $ hFlush cin - - -- uppstream or process is done. - -- process rest outputs. - liftIO $ hClose cin - repeatLoopT $ do - out <- liftIO $ S.hGetSome cout bufSize - when (S.null out) exit - lift $ yield out - - ec <- liftIO $ maybe (waitForProcess' ph) return end - lift $ when (ec /= ExitSuccess) $ monadThrow ec - - where - createp = createProcess cp - { std_in = CreatePipe - , std_out = CreatePipe - } - - closep (Just cin, Just cout, _, ph) = do - hClose cin - hClose cout - _ <- waitForProcess' ph - return () - - hReady' h = - hReady h `E.catch` \(E.SomeException _) -> return False - waitForProcess' ph = - waitForProcess ph `E.catch` \(E.SomeException _) -> return ExitSuccess - --- | Source of process -sourceProcess :: MonadResource m => CreateProcess -> GSource m S.ByteString -sourceProcess cp = CL.sourceNull >+> conduitProcess cp - --- | Conduit of shell command -conduitCmd :: MonadResource m => String -> GConduit S.ByteString m S.ByteString -conduitCmd = conduitProcess . shell - --- | Source of shell command -sourceCmd :: MonadResource m => String -> GSource m S.ByteString -sourceCmd = sourceProcess . shell
+ Data/Conduit/ProcessOld.hs view
@@ -0,0 +1,101 @@+{-# LANGUAGE FlexibleContexts, OverloadedStrings, BangPatterns, RankNTypes #-} +module Data.Conduit.ProcessOld ( + -- * Run process + sourceProcess, + conduitProcess, + + -- * Run shell command + sourceCmd, + conduitCmd, + + -- * Convenience re-exports + shell, + proc, + CreateProcess(..), + CmdSpec(..), + StdStream(..), + ProcessHandle, + ) where + +import qualified Control.Exception as E +import Control.Monad +import Control.Monad.Trans +import Control.Monad.Trans.Loop +import Control.Monad.Trans.Resource (MonadResource, monadThrow) +import qualified Data.ByteString as S +import Data.Conduit +import qualified Data.Conduit.List as CL +import Data.Maybe +import System.Exit (ExitCode(..)) +import System.IO +import System.Process + +bufSize :: Int +bufSize = 64 * 1024 + +-- | Conduit of process +conduitProcess + :: MonadResource m + => CreateProcess + -> Conduit S.ByteString m S.ByteString +conduitProcess cp = bracketP createp closep $ \(Just cin, Just cout, _, ph) -> do + end <- repeatLoopT $ do + -- if process's outputs are available, then yields them. + repeatLoopT $ do + b <- liftIO $ hReady' cout + when (not b) exit + out <- liftIO $ S.hGetSome cout bufSize + void $ lift . lift $ yield out + + -- if process exited, then exit + end <- liftIO $ getProcessExitCode ph + when (isJust end) $ exitWith end + + -- if upper stream ended, then exit + inp <- lift await + when (isNothing inp) $ exitWith Nothing + + -- put input to process + liftIO $ S.hPut cin $ fromJust inp + liftIO $ hFlush cin + + -- uppstream or process is done. + -- process rest outputs. + liftIO $ hClose cin + repeatLoopT $ do + out <- liftIO $ S.hGetSome cout bufSize + when (S.null out) exit + lift $ yield out + + ec <- liftIO $ maybe (waitForProcess' ph) return end + lift $ when (ec /= ExitSuccess) $ monadThrow ec + + where + createp = createProcess cp + { std_in = CreatePipe + , std_out = CreatePipe + } + + closep (Just cin, Just cout, _, ph) = do + hClose cin + hClose cout + _ <- waitForProcess' ph + return () + closep _ = error "Data.Conduit.Process.closep: Unhandled case" + + hReady' h = + hReady h `E.catch` \(E.SomeException _) -> return False + waitForProcess' ph = + waitForProcess ph `E.catch` \(E.SomeException _) -> return ExitSuccess + +-- | Source of process +sourceProcess :: MonadResource m => CreateProcess -> Producer m S.ByteString +sourceProcess cp = toProducer $ CL.sourceNull $= conduitProcess cp + +-- | Conduit of shell command +conduitCmd :: MonadResource m => String -> Conduit S.ByteString m S.ByteString +conduitCmd = conduitProcess . shell + +-- | Source of shell command +sourceCmd :: MonadResource m => String -> Producer m S.ByteString +sourceCmd = sourceProcess . shell
System/Process/QQ.hs view
@@ -8,6 +8,7 @@ ) where import Control.Applicative+import Control.Monad.Trans.Resource as R import qualified Data.ByteString.Lazy as BL import qualified Data.Conduit as C import qualified Data.Conduit.List as CL@@ -15,7 +16,7 @@ import Language.Haskell.TH.Quote import Text.Shakespeare.Text -import Data.Conduit.Process+import Data.Conduit.ProcessOld def :: QuasiQuoter def = QuasiQuoter@@ -28,7 +29,7 @@ -- | Command result of (Lazy) ByteString. cmd :: QuasiQuoter cmd = def { quoteExp = \str -> [|- BL.fromChunks <$> C.runResourceT (sourceCmd (LT.unpack $(quoteExp lt str)) C.$$ CL.consume)+ BL.fromChunks <$> runResourceT (sourceCmd (LT.unpack $(quoteExp lt str)) C.$$ CL.consume) |] } -- | Source of shell command
process-conduit.cabal view
@@ -1,17 +1,15 @@ name: process-conduit-version: 0.5.0.5-synopsis: Conduits for processes+version: 1.2.0.1+synopsis: Conduits for processes (deprecated) -description:- Conduits for processes.- For more details: <https://github.com/tanakh/process-conduit/blob/master/README.md>+description: This package is deprecated. Please use Data.Conduit.Process from conduit-extra instead. The original code is maintained in Data.Conduit.ProcessOld for those wishing to use the older API. -homepage: http://github.com/tanakh/process-conduit+homepage: http://github.com/snoyberg/process-conduit license: BSD3 license-file: LICENSE author: Hideyuki Tanaka-maintainer: Hideyuki Tanaka <tanaka.hideyuki@gmail.com>-copyright: (c) 2011-2012, Hideyuki Tanaka+maintainer: Michael Snoyman+copyright: (c) 2011-2013, Hideyuki Tanaka category: System, Conduit build-type: Simple cabal-version: >=1.8@@ -20,21 +18,23 @@ source-repository head type: git- location: git://github.com/tanakh/process-conduit.git+ location: git://github.com/snoyberg/process-conduit.git library- exposed-modules: Data.Conduit.Process+ exposed-modules: Data.Conduit.ProcessOld System.Process.QQ- + build-depends: base == 4.*- , template-haskell >= 2.4 && < 2.9+ , template-haskell >= 2.4 , mtl >= 2.0 , control-monad-loop == 0.1.* , bytestring >= 0.9 , text >= 0.11 , process >= 1.0- , conduit == 0.5.*+ , conduit >= 1.1+ , resourcet >= 1.1 , shakespeare-text >= 1.0+ , shakespeare ghc-options: -Wall @@ -46,4 +46,6 @@ , bytestring , hspec >= 1.3 , conduit+ , conduit-extra+ , resourcet , process-conduit
test.hs view
@@ -1,12 +1,13 @@ {-# LANGUAGE OverloadedStrings, QuasiQuotes #-} -import Data.Conduit.Process+import Data.Conduit.ProcessOld import System.Process.QQ import qualified Data.ByteString.Lazy.Char8 as L import Data.Conduit import qualified Data.Conduit.Binary as CB import Test.Hspec+import Control.Monad.Trans.Resource (runResourceT) main :: IO () main = hspec $ do