process-conduit (empty) → 0.0.0
raw patch · 8 files changed
+297/−0 lines, 8 filesdep +basedep +bytestringdep +conduitsetup-changed
Dependencies added: base, bytestring, conduit, mtl, process, process-conduit, shakespeare-text, template-haskell, text
Files
- Data/Conduit/Process.hs +72/−0
- LICENSE +30/−0
- README.md +76/−0
- Setup.hs +2/−0
- System/Process/QQ.hs +47/−0
- examples/TestConduit.hs +8/−0
- examples/TestQQ.hs +9/−0
- process-conduit.cabal +53/−0
+ Data/Conduit/Process.hs view
@@ -0,0 +1,72 @@+module Data.Conduit.Process (+ -- * run process+ sourceProcess,+ conduitProcess,+ + -- * run command+ sourceCmd,+ conduitCmd,+ + -- * Convenience re-exports+ shell,+ proc,+ CreateProcess(..),+ CmdSpec(..),+ StdStream(..),+ ProcessHandle,+ ) where++import Control.Exception+import Control.Monad+import Control.Monad.Trans+import qualified Data.ByteString as B+import qualified Data.Conduit as C+import qualified Data.Conduit.List as CL+import System.Exit+import System.IO+import System.Process++bufSize :: Int+bufSize = 64 * 1024++sourceProcess :: C.ResourceIO m => CreateProcess -> C.Source m B.ByteString+sourceProcess cp = CL.sourceNull C.$= conduitProcess cp++conduitProcess :: C.ResourceIO m => CreateProcess -> C.Conduit B.ByteString m B.ByteString+conduitProcess cp = C.conduitIO alloc cleanup push close+ where+ alloc = createProcess cp+ { std_in = CreatePipe+ , std_out = CreatePipe+ }++ cleanup _ =+ return ()+ + push (Just cin, Just cout, _, ph) bstr = liftIO $ do+ B.hPutStr cin bstr+ -- hFlush cin+ mbec <- getProcessExitCode ph+ case mbec of+ Nothing -> do+ str <- B.hGetNonBlocking cout bufSize+ return $ C.IOProducing [str]+ Just ec -> do+ when (ec /= ExitSuccess) $ throwIO ec+ return $ C.IOFinished Nothing []++ close (Just cin, Just cout, _, ph) = liftIO $ do+ hClose cin+ ec <- waitForProcess ph+ when (ec /= ExitSuccess) $ throwIO ec+ str <- B.hGetContents cout+ hClose cout+ return [str]++sourceCmd :: C.ResourceIO m => String -> C.Source m B.ByteString+sourceCmd cmd = CL.sourceNull C.$= conduitCmd cmd++conduitCmd :: C.ResourceIO m+ => String+ -> C.Conduit B.ByteString m B.ByteString+conduitCmd cmd = conduitProcess (shell cmd)
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c)2011-2012, Hideyuki Tanaka++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Hideyuki Tanaka nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,76 @@+process-conduit: Conduit for processes+===============================================++# About++This package provides [conduit](http://hackage.haskell.org/package/conduit)+for processes.+Also this provides quasi-quoters for process using it.++# Install++~~~ {.bash}+$ cabal update+$ cabal install process-conduit+~~~++# Document++Haddock documents are here:++<http://hackage.haskell.org/package/process-conduit>++# Quasi Quoters++process-conduit has three quasi-quoters, `cmd`, `scmd` and `ccmd`.++The result type of `cmd` is Lazy `ByteString`,+but execution will perform strictly.++The result type of `scmd` and `ccmd` are+`Source ByteString m ByteString` and+`Conduit ByteString m ByteString` respectively.++If a command is failed, an exception is thrown.++Commands are executed in ***run-time***, not compile-time.++# Examples++* Create a Source and a Conduit of process++~~~ {.haskell}+import qualified Data.Conduit as C+import qualified Data.Conduit.Binary as CB+import Data.Conduit.Process+import System.IO++main :: IO ()+main = C.runResourceT $ do+ sourceCmd "ls" C.$= conduitCmd "sort" C.$$ CB.sinkHandle stdout+~~~++* Invoke a process simply++~~~ {.haskell}+{-# LANGUAGE QuasiQuotes #-}+import System.Process.QQ++main = print =<< [cmd|ls|]+~~~++* Conduit Quasi-Quoters++~~~ {.haskell}+main :: IO ()+main = runResourceT $ do+ [scmd|ls|] $= [ccmd|sort|] $$ sinkHandle stdout+~~~++* Unquoting (syntax is same as [shakespeare-text](http://hackage.haskell.org/package/shakespeare-text))++~~~ {.haskell}+main = do+ [url] <- getArgs+ print =<< [cmd|curl #{url}|]+~~~
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ System/Process/QQ.hs view
@@ -0,0 +1,47 @@+{-# LANGUAGE TemplateHaskell #-}++module System.Process.QQ (+ cmd,+ lcmd,+ scmd,+ ccmd,+ ) where++import Control.Applicative+import Control.Monad+import Control.Monad.Trans+import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as BL+import qualified Data.Conduit as C+import qualified Data.Conduit.Lazy as CL+import qualified Data.Conduit.List as CL+import qualified Data.Text.Lazy as LT+import Language.Haskell.TH+import Language.Haskell.TH.Quote+import Text.Shakespeare.Text++import Data.Conduit.Process++def :: QuasiQuoter+def = QuasiQuoter+ { quoteExp = undefined+ , quotePat = undefined+ , quoteType = undefined+ , quoteDec = undefined+ }++cmd :: QuasiQuoter+cmd = def { quoteExp = \str -> [|+ BL.fromChunks <$> C.runResourceT (sourceCmd (LT.unpack $(quoteExp lt str)) C.$$ CL.consume)+|] }++lcmd :: QuasiQuoter+lcmd = def { quoteExp = \str -> [|+ BL.fromChunks <$> (CL.lazyConsume $ sourceCmd $ LT.unpack $(quoteExp lt str))+|] }++scmd :: QuasiQuoter+scmd = def { quoteExp = \str -> [| sourceCmd $(quoteExp lt str) |] }++ccmd :: QuasiQuoter+ccmd = def { quoteExp = \str -> [| conduitCmd $(quoteExp lt str) |] }
+ examples/TestConduit.hs view
@@ -0,0 +1,8 @@+import qualified Data.Conduit as C+import qualified Data.Conduit.Binary as CB+import Data.Conduit.Process+import System.IO++main :: IO ()+main = C.runResourceT $ do+ sourceCmd "ls" C.$= conduitCmd "sort" C.$$ CB.sinkHandle stdout
+ examples/TestQQ.hs view
@@ -0,0 +1,9 @@+{-# LANGUAGE QuasiQuotes #-}++import System.Process.QQ+import System.Environment++main :: IO ()+main = do+ [url] <- getArgs+ print =<< [cmd|curl #{url}|]
+ process-conduit.cabal view
@@ -0,0 +1,53 @@+Name: process-conduit+Version: 0.0.0+Synopsis: Conduit for process+Description: Conduit for process+Homepage: http://github.com/tanakh/process-conduit+License: BSD3+License-file: LICENSE+Author: Hideyuki Tanaka+Maintainer: Hideyuki Tanaka <tanaka.hideyuki@gmail.com>+Copyright: (c) 2011-2012, Hideyuki Tanaka+Category: System, Conduit+Build-type: Simple+Cabal-version: >=1.8++Extra-source-files: README.md++Source-repository head+ Type: git+ Location: git://github.com/tanakh/process-conduit.git++Flag examples+ Description: Build examples+ Default: False++Library+ Exposed-modules: Data.Conduit.Process+ System.Process.QQ+ + Build-depends: base == 4.*+ , template-haskell >= 2.4 && < 2.8+ , mtl == 2.0.*+ , bytestring == 0.9.*+ , text == 0.11.*+ , process == 1.1.*+ , conduit == 0.2.*+ , shakespeare-text == 0.10.*++Executable process-conduit+ Hs-source-dirs: examples+ Main-is: TestConduit.hs+ Build-depends: base == 4.*+ , conduit == 0.2.*+ , process-conduit+ if !flag(examples)+ Buildable: False++Executable process-qq+ Hs-source-dirs: examples+ Main-is: TestQQ.hs+ Build-depends: base == 4.*+ , process-conduit+ if !flag(examples)+ Buildable: False