Hello community, here is the log from the commit of package ghc-process-extras for openSUSE:Factory checked in at 2016-11-24 21:24:17 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-process-extras (Old) and /work/SRC/openSUSE:Factory/.ghc-process-extras.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-process-extras" Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-process-extras/ghc-process-extras.changes 2016-11-15 17:56:52.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.ghc-process-extras.new/ghc-process-extras.changes 2016-11-24 21:24:18.000000000 +0100 @@ -1,0 +2,5 @@ +Thu Sep 15 06:55:19 UTC 2016 - psim...@suse.com + +- Update to version 0.4.1.4 revision 0 with cabal2obs. + +------------------------------------------------------------------- Old: ---- process-extras-0.3.3.8.tar.gz New: ---- process-extras-0.4.1.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-process-extras.spec ++++++ --- /var/tmp/diff_new_pack.qLuvRt/_old 2016-11-24 21:24:19.000000000 +0100 +++ /var/tmp/diff_new_pack.qLuvRt/_new 2016-11-24 21:24:19.000000000 +0100 @@ -18,15 +18,14 @@ %global pkg_name process-extras Name: ghc-%{pkg_name} -Version: 0.3.3.8 +Version: 0.4.1.4 Release: 0 Summary: Process extras License: MIT -Group: System/Libraries +Group: Development/Languages/Other Url: https://hackage.haskell.org/package/%{pkg_name} Source0: https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz BuildRequires: ghc-Cabal-devel -# Begin cabal-rpm deps: BuildRequires: ghc-ListLike-devel BuildRequires: ghc-bytestring-devel BuildRequires: ghc-deepseq-devel @@ -35,7 +34,6 @@ BuildRequires: ghc-rpm-macros BuildRequires: ghc-text-devel BuildRoot: %{_tmppath}/%{name}-%{version}-build -# End cabal-rpm deps %description Extends <http://hackage.haskell.org/package/process>. Read process input and @@ -57,15 +55,12 @@ %prep %setup -q -n %{pkg_name}-%{version} - %build %ghc_lib_build - %install %ghc_lib_install - %post devel %ghc_pkg_recache @@ -78,6 +73,6 @@ %files devel -f %{name}-devel.files %defattr(-,root,root,-) -%doc README.md +%doc README.md changelog %changelog ++++++ process-extras-0.3.3.8.tar.gz -> process-extras-0.4.1.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/process-extras-0.3.3.8/.ghci new/process-extras-0.4.1.4/.ghci --- old/process-extras-0.3.3.8/.ghci 1970-01-01 01:00:00.000000000 +0100 +++ new/process-extras-0.4.1.4/.ghci 2016-05-15 18:23:39.000000000 +0200 @@ -0,0 +1,4 @@ +:set -isrc +:set -DMIN_VERSION_deepseq(a,b,c)=1 +:set -DMIN_VERSION_bytestring(a,b,c)=1 +:load System.Process.ListLike diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/process-extras-0.3.3.8/README.md new/process-extras-0.4.1.4/README.md --- old/process-extras-0.3.3.8/README.md 2016-01-26 22:16:51.000000000 +0100 +++ new/process-extras-0.4.1.4/README.md 2016-05-15 18:23:39.000000000 +0200 @@ -3,11 +3,65 @@ Extra functionality for the [Process library](http://hackage.haskell.org/package/process). * Read process input and output as ByteStrings or Text, or write your own ProcessOutput instance. - * Lazy process input and output. + * Lazy process input and output (i.e. read output from processes that run forever.) * ProcessMaker class for more flexibility in the process creation API. # Contributing This project is available on [GitHub](https://github.com/seereason/process-extras). You may contribute changes there. -Please report bugs and feature requests using the [GitHub issue tracker](https://github.com/ddssff/process-extras/issues). +Please report bugs and feature requests using the [GitHub issue tracker](https://github.com/seereason/process-extras/issues). + +# Examples: + +The output type of the raw system process functions is ByteString. +Instances of ListLikeProcessIO are provided to read as type String, +Text, Lazy Text, ByteString, or Lazy ByteString. Select by casting +the result, or by specifying the module containing the specialized +function: + + > :m +System.Process.ListLike Data.ByteString Data.Text.Lazy + > readCreateProcessWithExitCode (shell "echo 'λ'") mempty :: IO (ExitCode, ByteString, ByteString) + (ExitSuccess,"\206\187\n","") + > readCreateProcessWithExitCode (shell "echo 'λ'") mempty :: IO (ExitCode, Text, Text) + (ExitSuccess,"\955\n","") + > readCreateProcessWithExitCode (shell "echo 'λ'") mempty :: IO (ExitCode, String, String) + (ExitSuccess,"\955\n","") + > System.Process.Text.readCreateProcessWithExitCode (shell "yes | head -10") mempty + (ExitSuccess,"y\ny\ny\ny\ny\ny\ny\ny\ny\ny\n","") + +Although the output *type* can be lazy, normal process functions still +need to read until EOF on the process output before returing anything. +If you have a process whose output never ends you can use the +readCreateProcessLazy function to read it. Functions like readProcess +would block waiting for EOF on the process output: + + > (Prelude.take 4 <$> readCreateProcessLazy (proc "yes" []) mempty :: IO [Chunk Text]) >>= mapM_ (putStrLn . show) + ProcessHandle <process> + Stdout "y\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny ..." + ... + +The output type can be any instance of ProcessOutput, instances for +types (ExitCode, a, a), [Chunk a], and (ExitCode, [Chunk a]) are +provided. [Chunk a] can be converted to any other instance of +ProcessOutput using collectOutput + + > (readCreateProcess (shell "gzip -v < /proc/uptime") mempty :: IO [Chunk ByteString]) >>= mapM_ (putStrLn . show) + Stdout "\US\139\b\NUL\237\136\&7W\NUL\ETX345\183\&403\215\&31Q04267\177\&0\177\212\&33\225\STX\NUL_\169\142\178\ETB\NUL\NUL\NUL" + Stderr "gzip: stdin: file size changed while zipping\n -8.7%\n" + Result ExitSuccess + > (readCreateProcess (shell "uptime") mempty :: IO [Chunk ByteString]) >>= writeOutput + 14:00:34 up 18 days, 7:16, 6 users, load average: 0.04, 0.10, 0.08 + > collectOutput <$> (readCreateProcess (shell "gzip -v < /proc/uptime") mempty :: IO [Chunk ByteString]) :: IO (ExitCode, ByteString, ByteString) + (ExitSuccess,"\US\139\b\NUL\185\137\&7W\NUL\ETX345\183\&427\212\&33W0426731\177\208\&35\225\STX\NUL\237\192\CAN\224\ETB\NUL\NUL\NUL","gzip: stdin: file size changed while zipping\n -8.7%\n") + > collectOutput <$> (readCreateProcess (shell "gzip -v < /proc/uptime") mempty :: IO [Chunk ByteString]) :: IO (ExitCode, ByteString, ByteString) + (ExitSuccess,"\US\139\b\NUL\185\137\&7W\NUL\ETX345\183\&427\212\&33W0426731\177\208\&35\225\STX\NUL\237\192\CAN\224\ETB\NUL\NUL\NUL","gzip: stdin: file size changed while zipping\n -8.7%\n") + > (collectOutput . filter (\x -> case x of Stderr _ -> False; _ -> True)) <$> (readCreateProcess (shell "gzip -v < /proc/uptime") mempty :: IO [Chunk ByteString]) :: IO (ExitCode, ByteString, ByteString) + (ExitSuccess,"\US\139\b\NUL<\138\&7W\NUL\ETX345\183\&410\210\&3\176P04267713\213\&37\224\STX\NULT\142\EOT\165\ETB\NUL\NUL\NUL","") + +Some cases that need investigation: + + > (readCreateProcess (shell "gzip -v < /proc/uptime") mempty :: IO [Chunk String]) >>= mapM_ (putStrLn . show) + *** Exception: fd:13: hGetContents: invalid argument (invalid byte sequence) + > (readCreateProcess (shell "gzip -v < /proc/uptime") mempty :: IO [Chunk Text]) >>= mapM_ (putStrLn . show) + *** Exception: fd:13: hClose: invalid argument (Bad file descriptor) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/process-extras-0.3.3.8/changelog new/process-extras-0.4.1.4/changelog --- old/process-extras-0.3.3.8/changelog 1970-01-01 01:00:00.000000000 +0100 +++ new/process-extras-0.4.1.4/changelog 2016-05-15 18:23:39.000000000 +0200 @@ -0,0 +1,21 @@ +haskell-process-extras (0.4.1.4) unstable; urgency=low + + * Add changelog and .ghci to Extra-Source-Files list. + + -- David Fox <d...@seereason.com> Sun, 15 May 2016 09:20:54 -0700 + +haskell-process-extras (0.4.1.3) unstable; urgency=low + + * Actually check changelog into git. + + -- David Fox <d...@seereason.com> Sun, 15 May 2016 09:00:03 -0700 + +haskell-process-extras (0.4) trusty-seereason; urgency=low + + * Add changelog + * Wrap all the input processing with a catch resource vanished + exception. + * Add foldOutput and writeOutput, for handling Chunk streams. + * Add some examples in README.md. + + -- David Fox <d...@seereason.com> Sun, 15 May 2016 08:59:47 -0700 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/process-extras-0.3.3.8/process-extras.cabal new/process-extras-0.4.1.4/process-extras.cabal --- old/process-extras-0.3.3.8/process-extras.cabal 2016-01-26 22:16:51.000000000 +0100 +++ new/process-extras-0.4.1.4/process-extras.cabal 2016-05-15 18:23:39.000000000 +0200 @@ -1,5 +1,5 @@ Name: process-extras -Version: 0.3.3.8 +Version: 0.4.1.4 Synopsis: Process extras Description: Extends <http://hackage.haskell.org/package/process>. Read process input and output as ByteStrings or @@ -15,7 +15,7 @@ Build-type: Simple Cabal-version: >=1.6 Extra-source-files: - README.md, .travis.yml + README.md, .travis.yml, .ghci, changelog Tested-With: GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3, GHC >= 8 source-repository head diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/process-extras-0.3.3.8/src/System/Process/Common.hs new/process-extras-0.4.1.4/src/System/Process/Common.hs --- old/process-extras-0.3.3.8/src/System/Process/Common.hs 2016-01-26 22:16:51.000000000 +0100 +++ new/process-extras-0.4.1.4/src/System/Process/Common.hs 2016-05-15 18:23:39.000000000 +0200 @@ -20,7 +20,7 @@ import Control.DeepSeq (NFData) import Control.Exception as E (SomeException, onException, catch, mask, throw, try) import Control.Monad -import Data.ListLike (null) +import Data.ListLike as ListLike (null) import Data.ListLike.IO (ListLikeIO, hGetContents, hPutStr) import Data.Monoid ((<>)) import Generics.Deriving.Instances () @@ -33,7 +33,7 @@ import Utils (forkWait) #if __GLASGOW_HASKELL__ <= 709 -import Control.Applicative (pure, (<$>), (<*>)) +import Control.Applicative ((<$>), (<*>)) import Data.Monoid (Monoid(mempty, mappend)) #endif @@ -118,9 +118,8 @@ -- fork off a thread to start consuming stderr waitErr <- forkWait $ errf <$> (hGetContents errh >>= forceOutput) - -- now write and flush any input - unless (null input) $ do ignoreResourceVanished (hPutStr inh input); hFlush inh - hClose inh -- done with stdin + -- now write and flush any input. + writeInput inh input -- wait on the output out <- waitOut @@ -134,13 +133,6 @@ return $ out <> err <> ex -ignoreResourceVanished :: IO () -> IO () -ignoreResourceVanished action = - try action >>= either ignoreResourceVanished' return - where - ignoreResourceVanished' e | ioe_type e == ResourceVanished = return () - ignoreResourceVanished' e = throw e - -- | Like readCreateProcess, but the output is read lazily. readCreateProcessLazy :: (ProcessMaker maker, ProcessOutput a b, ListLikeProcessIO a c) => maker -> a -> IO b readCreateProcessLazy maker input = mask $ \restore -> do @@ -150,7 +142,7 @@ do -- fork off a thread to start consuming stdout -- Without unsafeIntereleaveIO the pid messsage gets stuck -- until some additional output arrives from the process. - waitOut <- forkWait $ (<>) <$> pure (pidf pid) + waitOut <- forkWait $ (<>) <$> return (pidf pid) <*> unsafeInterleaveIO (readInterleaved [(outf, outh), (errf, errh)] (codef <$> waitForProcess pid)) writeInput inh input waitOut) @@ -194,13 +186,17 @@ -- Catch and ignore Resource Vanished exceptions, they just mean the -- process exited before all of its output was read. writeInput :: ListLikeProcessIO a c => Handle -> a -> IO () -writeInput inh input = do - (do unless (null input) (hPutStr inh input >> hFlush inh) - hClose inh) `E.catch` resourceVanished (\ _ -> return ()) +writeInput inh input = + ignoreResourceVanished $ do + unless (ListLike.null input) $ do + hPutStr inh input + hFlush inh + hClose inh -- stdin has been fully written -- | Wrapper for a process that provides a handler for the -- ResourceVanished exception. This is frequently an exception we -- wish to ignore, because many processes will deliberately exit -- before they have read all of their input. -resourceVanished :: (IOError -> IO a) -> IOError -> IO a -resourceVanished epipe e = if ioe_type e == ResourceVanished then epipe e else ioError e +ignoreResourceVanished :: IO () -> IO () +ignoreResourceVanished action = + action `E.catch` (\e -> if ioe_type e == ResourceVanished then return () else ioError e) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/process-extras-0.3.3.8/src/System/Process/ListLike.hs new/process-extras-0.4.1.4/src/System/Process/ListLike.hs --- old/process-extras-0.3.3.8/src/System/Process/ListLike.hs 2016-01-26 22:16:51.000000000 +0100 +++ new/process-extras-0.4.1.4/src/System/Process/ListLike.hs 2016-05-15 18:23:39.000000000 +0200 @@ -17,20 +17,25 @@ , readProcessWithExitCode , Chunk(..) , collectOutput + , foldOutput + , writeOutput , showCreateProcessForUser , showCmdSpecForUser + , proc + , shell ) where import Control.DeepSeq (force) import Control.Exception as C (evaluate, SomeException, throw) -import Data.ListLike.IO (hGetContents) +import Data.ListLike.IO (hGetContents, hPutStr, ListLikeIO) #if __GLASGOW_HASKELL__ <= 709 import Data.Monoid (mempty, mconcat) #endif import Data.Text (unpack) import Data.Text.Lazy (Text, toChunks) import System.Exit (ExitCode) -import System.Process (CmdSpec(..), CreateProcess(..), ProcessHandle, showCommandForUser) +import System.IO (stdout, stderr) +import System.Process (CmdSpec(..), CreateProcess(..), proc, ProcessHandle, shell, showCommandForUser) import System.Process.ByteString () import System.Process.ByteString.Lazy () import System.Process.Common (ProcessMaker(process), ListLikeProcessIO(forceOutput, readChunks), ProcessOutput(pidf, outf, errf, codef, intf), @@ -70,6 +75,10 @@ | Result ExitCode | Exception SomeException -- ^ Note that the instances below do not use this constructor. + deriving Show + +instance Show ProcessHandle where + show _ = "<process>" instance ListLikeProcessIO a c => ProcessOutput a [Chunk a] where pidf p = [ProcessHandle p] @@ -85,11 +94,29 @@ errf x = (mempty, [Stderr x]) intf e = throw e +foldOutput :: (ProcessHandle -> r) + -> (a -> r) + -> (a -> r) + -> (SomeException -> r) + -> (ExitCode -> r) + -> Chunk a + -> r +foldOutput p _ _ _ _ (ProcessHandle x) = p x +foldOutput _ o _ _ _ (Stdout x) = o x +foldOutput _ _ e _ _ (Stderr x) = e x +foldOutput _ _ _ i _ (Exception x) = i x +foldOutput _ _ _ _ r (Result x) = r x + -- | Turn a @[Chunk a]@ into any other instance of 'ProcessOutput'. collectOutput :: ProcessOutput a b => [Chunk a] -> b -collectOutput xs = mconcat $ map (\ chunk -> case chunk of - ProcessHandle x -> pidf x - Stdout x -> outf x - Stderr x -> errf x - Result x -> codef x - Exception x -> intf x) xs +collectOutput xs = mconcat $ map (foldOutput pidf outf errf intf codef) xs + +-- | Send Stdout chunks to stdout and Stderr chunks to stderr. +writeOutput :: ListLikeIO a c => [Chunk a] -> IO () +writeOutput [] = return () +writeOutput (x : xs) = + foldOutput (\_ -> return ()) + (hPutStr stdout) + (hPutStr stderr) + (\_ -> return ()) + (\_ -> return ()) x >> writeOutput xs