packages feed

coquina 0.1.0.1 → 0.2.0.0

raw patch · 6 files changed

+49/−30 lines, 6 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Coquina.Internal: ignoreSigPipe :: IO () -> IO ()
- Coquina: Shell :: ExceptT Int (WriterT (Text, Text) m) a -> Shell (m :: Type -> Type) a
+ Coquina: Shell :: ExceptT Int (WriterT (Text, Text) m) a -> Shell m a
- Coquina: StreamingProcess :: !Shell m ExitCode -> !Shell m () -> !Shell m (Maybe ExitCode) -> StreamingProcess (m :: Type -> Type)
+ Coquina: StreamingProcess :: !Shell m ExitCode -> !Shell m () -> !Shell m (Maybe ExitCode) -> StreamingProcess m
- Coquina: [_streamingProcess_getProcessExitCode] :: StreamingProcess (m :: Type -> Type) -> !Shell m (Maybe ExitCode)
+ Coquina: [_streamingProcess_getProcessExitCode] :: StreamingProcess m -> !Shell m (Maybe ExitCode)
- Coquina: [_streamingProcess_terminateProcess] :: StreamingProcess (m :: Type -> Type) -> !Shell m ()
+ Coquina: [_streamingProcess_terminateProcess] :: StreamingProcess m -> !Shell m ()
- Coquina: [_streamingProcess_waitForProcess] :: StreamingProcess (m :: Type -> Type) -> !Shell m ExitCode
+ Coquina: [_streamingProcess_waitForProcess] :: StreamingProcess m -> !Shell m ExitCode
- Coquina: [unShell] :: Shell (m :: Type -> Type) a -> ExceptT Int (WriterT (Text, Text) m) a
+ Coquina: [unShell] :: Shell m a -> ExceptT Int (WriterT (Text, Text) m) a
- Coquina: class Monad m => MonadShell (m :: Type -> Type)
+ Coquina: class Monad m => MonadShell m
- Coquina: data StreamingProcess (m :: Type -> Type)
+ Coquina: data StreamingProcess m
- Coquina: hoistShell :: (forall x. () => m x -> n x) -> Shell m a -> Shell n a
+ Coquina: hoistShell :: (forall x. m x -> n x) -> Shell m a -> Shell n a
- Coquina: inTempDirectory :: forall (m :: Type -> Type) a. MonadIO m => String -> (FilePath -> Shell IO a) -> Shell m a
+ Coquina: inTempDirectory :: MonadIO m => String -> (FilePath -> Shell IO a) -> Shell m a
- Coquina: newtype Shell (m :: Type -> Type) a
+ Coquina: newtype Shell m a
- Coquina: run :: forall (m :: Type -> Type). MonadIO m => CreateProcess -> Shell m ()
+ Coquina: run :: MonadIO m => CreateProcess -> Shell m ()
- Coquina: shellCreateProcess :: forall (m :: Type -> Type). MonadIO m => CreateProcess -> Shell m ()
+ Coquina: shellCreateProcess :: MonadIO m => CreateProcess -> Shell m ()
- Coquina: shellCreateProcessWith :: forall (m :: Type -> Type). MonadIO m => (CreateProcess -> IO (ExitCode, Text, Text)) -> CreateProcess -> Shell m ()
+ Coquina: shellCreateProcessWith :: MonadIO m => (CreateProcess -> IO (ExitCode, Text, Text)) -> CreateProcess -> Shell m ()
- Coquina: shellCreateProcessWithEnv :: forall (m :: Type -> Type). MonadIO m => Map String String -> CreateProcess -> Shell m ()
+ Coquina: shellCreateProcessWithEnv :: MonadIO m => Map String String -> CreateProcess -> Text -> Shell m ()
- Coquina: shellCreateProcessWithStdOut :: forall (m :: Type -> Type). MonadIO m => Handle -> CreateProcess -> Shell m ()
+ Coquina: shellCreateProcessWithStdOut :: MonadIO m => Handle -> CreateProcess -> Shell m ()
- Coquina: shellStreamableProcess :: forall (m :: Type -> Type). (MonadIO m, MonadMask m) => (ByteString -> IO ()) -> (ByteString -> IO ()) -> CreateProcess -> Shell m (StreamingProcess m)
+ Coquina: shellStreamableProcess :: (MonadIO m, MonadMask m) => (ByteString -> IO ()) -> (ByteString -> IO ()) -> CreateProcess -> Shell m (StreamingProcess m)
- Coquina: shellStreamableProcessBuffered :: forall (m :: Type -> Type). (MonadIO m, MonadMask m) => CreateProcess -> Shell m (StreamingProcess m, IO ByteString, IO ByteString)
+ Coquina: shellStreamableProcessBuffered :: (MonadIO m, MonadMask m) => CreateProcess -> Shell m (StreamingProcess m, IO ByteString, IO ByteString)
- Coquina.Internal: readAndDecodeCreateProcess :: CreateProcess -> IO (ExitCode, Text, Text)
+ Coquina.Internal: readAndDecodeCreateProcess :: CreateProcess -> Text -> IO (ExitCode, Text, Text)

Files

CHANGELOG.md view
@@ -1,5 +1,9 @@ # Revision history for coquina +## 0.2.0.0++* `shellCreateProcessWithEnv` now takes an additional argument for stdin+ ## 0.1.0.1  * Loosen version bounds
README.lhs view
@@ -1,6 +1,3 @@-# MOVED TO [GITHUB](https://github.com/obsidiansystems/coquina)-- # coquina [![Haskell](https://img.shields.io/badge/language-Haskell-orange.svg)](https://haskell.org) [![Hackage](https://img.shields.io/hackage/v/coquina.svg)](https://hackage.haskell.org/package/coquina) [![Hackage CI](https://matrix.hackage.haskell.org/api/v2/packages/coquina/badge)](https://matrix.hackage.haskell.org/#/package/coquina) [![Github CI](https://github.com/obsidiansystems/coquina/workflows/github-action/badge.svg)](https://github.com/obsidiansystems/coquina/actions) [![BSD3 License](https://img.shields.io/badge/license-BSD3-blue.svg)](https://github.com/obsidiansystems/coquina/blob/master/LICENSE) 
README.md view
@@ -1,6 +1,3 @@-# MOVED TO [GITHUB](https://github.com/obsidiansystems/coquina)-- # coquina [![Haskell](https://img.shields.io/badge/language-Haskell-orange.svg)](https://haskell.org) [![Hackage](https://img.shields.io/hackage/v/coquina.svg)](https://hackage.haskell.org/package/coquina) [![Hackage CI](https://matrix.hackage.haskell.org/api/v2/packages/coquina/badge)](https://matrix.hackage.haskell.org/#/package/coquina) [![Github CI](https://github.com/obsidiansystems/coquina/workflows/github-action/badge.svg)](https://github.com/obsidiansystems/coquina/actions) [![BSD3 License](https://img.shields.io/badge/license-BSD3-blue.svg)](https://github.com/obsidiansystems/coquina/blob/master/LICENSE) 
coquina.cabal view
@@ -1,6 +1,6 @@ cabal-version:      >=1.10 name:               coquina-version:            0.1.0.1+version:            0.2.0.0 synopsis:           Yet another shell monad. description:        A simple monad for shelling out from Haskell programs. bug-reports:        https://github.com/obsidiansystems/coquina/issues
src/Coquina.hs view
@@ -158,7 +158,7 @@  -- | Run a 'CreateProcess' in a 'Shell' shellCreateProcess :: MonadIO m => CreateProcess -> Shell m ()-shellCreateProcess = shellCreateProcessWithEnv mempty+shellCreateProcess p = shellCreateProcessWithEnv mempty p ""  -- | Run a 'CreateProcess' in a 'Shell' run :: MonadIO m => CreateProcess -> Shell m ()@@ -269,18 +269,19 @@   :: MonadIO m   => Map String String   -> CreateProcess+  -> Text -- ^ stdin   -> Shell m ()-shellCreateProcessWithEnv envOverrides = shellCreateProcessWith f+shellCreateProcessWithEnv envOverrides cmd' stdin = shellCreateProcessWith f cmd'   where     f cmd = do       envWithOverrides <- liftIO $ if Map.null envOverrides         then return $ env cmd         else Just . Map.toList . Map.union envOverrides . Map.fromList <$> getEnvironment-      readAndDecodeCreateProcess $ cmd { env = envWithOverrides }+      readAndDecodeCreateProcess (cmd { env = envWithOverrides }) stdin  -- | Execute a shell process with environment variables runCreateProcessWithEnv :: Map String String -> CreateProcess -> IO (ExitCode, Text, Text)-runCreateProcessWithEnv menv p = execShell $ shellCreateProcessWithEnv menv p+runCreateProcessWithEnv menv p = execShell $ shellCreateProcessWithEnv menv p ""  -- | Execute a shell process runCreateProcess :: CreateProcess -> IO (ExitCode, Text, Text)
src/Coquina/Internal.hs view
@@ -1,29 +1,31 @@ module Coquina.Internal where -import Control.Concurrent (MVar, newEmptyMVar, forkIO, putMVar, takeMVar, killThread)+import Control.Concurrent (MVar, forkIO, killThread, newEmptyMVar, putMVar, takeMVar) import Control.DeepSeq (rnf)-import Control.Exception (SomeException, evaluate, mask, try, throwIO, onException)+import Control.Exception (SomeException, evaluate, mask, onException, throwIO, try)+import qualified Control.Exception as C+import Control.Monad import Data.ByteString (hGetContents) import Data.Text (Text)+import qualified Data.Text as T import Data.Text.Encoding (decodeUtf8)-import System.Process+import qualified Data.Text.IO as T+import Foreign.C.Error (Errno(..), ePIPE)+import GHC.IO.Exception (IOErrorType(..), IOException(..)) import System.Exit import System.IO (hClose)---- | The code below is taken from System.Process which unfortunately does not export this function-withForkWait :: IO () -> (IO () ->  IO a) -> IO a-withForkWait async body = do-  waitVar <- newEmptyMVar :: IO (MVar (Either SomeException ()))-  mask $ \restore -> do-    tid <- forkIO $ try (restore async) >>= putMVar waitVar-    let wait = takeMVar waitVar >>= either throwIO return-    restore (body wait) `onException` killThread tid+import System.Process --- | Like readCreateProcess, but ignores stdin and decodes bytes, assuming utf-8-readAndDecodeCreateProcess :: CreateProcess -> IO (ExitCode, Text, Text)-readAndDecodeCreateProcess cp =-  withCreateProcess (cp { std_out = CreatePipe, std_err = CreatePipe }) $ \_ mouth merrh ph -> case (mouth, merrh) of-    (Just outh, Just errh) -> do+-- | Like readCreateProcess+readAndDecodeCreateProcess :: CreateProcess -> Text -> IO (ExitCode, Text, Text)+readAndDecodeCreateProcess cp input =+  withCreateProcess (cp { std_in = CreatePipe, std_out = CreatePipe, std_err = CreatePipe }) $ \mstdin mouth merrh ph -> case (mstdin, mouth, merrh) of+    (Just inh, Just outh, Just errh) -> do+      -- Write stdin+      unless (T.null input) $ do+        ignoreSigPipe $ T.hPutStr inh input+      -- hClose performs implicit hFlush, and thus may trigger a SIGPIPE+      ignoreSigPipe $ hClose inh       out <- fmap decodeUtf8 $ hGetContents outh       err <- fmap decodeUtf8 $ hGetContents errh       withForkWait (evaluate $ rnf out) $ \waitOut ->@@ -34,5 +36,23 @@           hClose errh       exitCode <- waitForProcess ph       return (exitCode, out, err)-    (Nothing, _) -> error "readAndDecodeCreateProcess: Failed to get std_out handle"-    (Just _, Nothing) -> error "readAndDecodeCreateProcess: Failed to get std_err handle"+    (Nothing, _, _) -> error "readAndDecodeCreateProcess: Failed to get std_in handle"+    (_, Nothing, _) -> error "readAndDecodeCreateProcess: Failed to get std_out handle"+    (_, _, Nothing) -> error "readAndDecodeCreateProcess: Failed to get std_err handle"++-- * The code below is taken from System.Process which unfortunately does not export these functions++-- | From System.Process+withForkWait :: IO () -> (IO () ->  IO a) -> IO a+withForkWait async body = do+  waitVar <- newEmptyMVar :: IO (MVar (Either SomeException ()))+  mask $ \restore -> do+    tid <- forkIO $ try (restore async) >>= putMVar waitVar+    let wait = takeMVar waitVar >>= either throwIO return+    restore (body wait) `onException` killThread tid++-- | From System.Process+ignoreSigPipe :: IO () -> IO ()+ignoreSigPipe = C.handle $ \e -> case e of+  IOError { ioe_type  = ResourceVanished, ioe_errno = Just ioe } | Errno ioe == ePIPE -> return ()+  _ -> throwIO e