shellmate 0.3.4 → 0.3.4.1
raw patch · 4 files changed
+28/−11 lines, 4 files
Files
- Control/Shell.hs +1/−1
- Control/Shell/Base.hs +17/−1
- Control/Shell/Internal.hs +9/−8
- shellmate.cabal +1/−1
Control/Shell.hs view
@@ -6,7 +6,7 @@ , shell, shell_, exitString -- * Error handling and control flow- , (|>), capture, captureStdErr, capture2, stream, lift+ , (|>), capture, captureStdErr, capture2, capture3, stream, lift , try, orElse, exit , Guard (..), guard, when, unless
Control/Shell/Base.hs view
@@ -7,7 +7,7 @@ , MonadIO (..), shellEnv , shell_ , stdin, echo, echo_, ask- , capture, captureStdErr, capture2, stream, lift+ , capture, captureStdErr, capture2, capture3, stream, lift , takeEnvLock, releaseEnvLock, setShellEnv, joinResult, absPath ) where import qualified System.Process as Proc@@ -16,6 +16,7 @@ import qualified System.Directory as Dir import qualified System.Environment as Env import System.FilePath+import Data.Either (either) import Data.IORef import Control.Monad.IO.Class import System.IO.Unsafe@@ -115,6 +116,21 @@ o <- IO.hGetContents ro e <- IO.hGetContents re return (o, e)++-- | Perform the given computation and return its standard output and error,+-- as well as its exit reason, in that order.+capture3 :: Shell () -> Shell (String, String, ExitReason)+capture3 m = do+ env <- getEnv+ (ro, wo) <- unsafeLiftIO Proc.createPipe+ (re, we) <- unsafeLiftIO Proc.createPipe+ res <- inEnv (env {envStdOut = wo, envStdErr = we}) $ try m+ unsafeLiftIO $ do+ IO.hClose wo+ IO.hClose we+ o <- IO.hGetContents ro+ e <- IO.hGetContents re+ return (o, e, either Failure (const Success) res) -- | Lift a pure function to a computation over standard input/output. -- Similar to 'interact'.
Control/Shell/Internal.hs view
@@ -94,9 +94,10 @@ ((stepenv, step) : steps) <- mkEnvs env p ma <- waitPids =<< mapM (uncurry (runStep True)) steps mb <- waitPids . (:[]) =<< runStep False stepenv step- case ma >> mb of- Just err -> pure $ Left err- _ -> pure $ Right ()+ case (ma, mb) of+ (Failure err, _) -> pure $ Left (Failure err)+ (_, Failure err) -> pure $ Left (Failure err)+ _ -> pure $ Right () where except = \(Ex.SomeException e) -> pure $ Left (Failure (show e)) runSh _ Done = do@@ -177,23 +178,23 @@ -- | Wait for all processes in the given list. If a process has failed, its -- error message is returned and the rest are killed.-waitPids :: [Pid] -> IO (Maybe ExitReason)+waitPids :: [Pid] -> IO ExitReason waitPids (PID cmd p : ps) = do exCode <- Proc.waitForProcess p case exCode of Exit.ExitFailure ec -> do mapM_ killPid ps- return . Just $ Failure $ "Command '" ++ cmd ++ "' failed with error "- ++" code " ++ show ec+ return . Failure $ concat+ ["Command `", cmd, "' failed with error code ", show ec] _ -> do waitPids ps waitPids (TID v _ : ps) = do merr <- Conc.takeMVar v case merr of- Just e -> mapM_ killPid ps >> return (Just e)+ Just e -> mapM_ killPid ps >> return e _ -> waitPids ps waitPids _ = do- return Nothing+ return Success -- | Execute an external command. No globbing, escaping or other external shell -- magic is performed on either the command or arguments. The program's
shellmate.cabal view
@@ -1,5 +1,5 @@ name: shellmate-version: 0.3.4+version: 0.3.4.1 synopsis: Simple interface for shell scripting in Haskell. description: Aims to simplify development of cross-platform shell scripts and similar things. homepage: https://github.com/valderman/shellmate