shellmate 0.3.4.1 → 0.3.4.2
raw patch · 3 files changed
+42/−20 lines, 3 filesdep ~directorydep ~process
Dependency ranges changed: directory, process
Files
- Control/Shell/Base.hs +28/−6
- Control/Shell/Internal.hs +10/−10
- shellmate.cabal +4/−4
Control/Shell/Base.hs view
@@ -91,16 +91,24 @@ capture m = do env <- getEnv (r, w) <- unsafeLiftIO Proc.createPipe+ v <- unsafeLiftIO $ Conc.newEmptyMVar+ unsafeLiftIO $ Conc.forkIO $ do+ s <- IO.hGetContents r+ Conc.putMVar v $! length s `seq` s inEnv (env {envStdOut = w}) m- unsafeLiftIO $ IO.hClose w >> IO.hGetContents r+ unsafeLiftIO $ IO.hClose w >> Conc.takeMVar v -- | Perform the given computation and return its standard error. captureStdErr :: Shell () -> Shell String captureStdErr m = do env <- getEnv (r, w) <- unsafeLiftIO Proc.createPipe+ v <- unsafeLiftIO $ Conc.newEmptyMVar+ unsafeLiftIO $ Conc.forkIO $ do+ s <- IO.hGetContents r+ Conc.putMVar v $! length s `seq` s inEnv (env {envStdErr = w}) m- unsafeLiftIO $ IO.hClose w >> IO.hGetContents r+ unsafeLiftIO $ IO.hClose w >> Conc.takeMVar v -- | Perform the given computation and return its standard output and error, -- in that order.@@ -109,12 +117,19 @@ env <- getEnv (ro, wo) <- unsafeLiftIO Proc.createPipe (re, we) <- unsafeLiftIO Proc.createPipe+ vo <- unsafeLiftIO $ Conc.newEmptyMVar+ ve <- unsafeLiftIO $ Conc.newEmptyMVar+ unsafeLiftIO $ Conc.forkIO $ do+ so <- IO.hGetContents ro+ se <- IO.hGetContents re+ Conc.putMVar vo $! length so `seq` so+ Conc.putMVar ve $! length se `seq` se inEnv (env {envStdOut = wo, envStdErr = we}) m unsafeLiftIO $ do IO.hClose wo IO.hClose we- o <- IO.hGetContents ro- e <- IO.hGetContents re+ o <- Conc.takeMVar vo+ e <- Conc.takeMVar ve return (o, e) -- | Perform the given computation and return its standard output and error,@@ -124,12 +139,19 @@ env <- getEnv (ro, wo) <- unsafeLiftIO Proc.createPipe (re, we) <- unsafeLiftIO Proc.createPipe+ vo <- unsafeLiftIO $ Conc.newEmptyMVar+ ve <- unsafeLiftIO $ Conc.newEmptyMVar+ unsafeLiftIO $ Conc.forkIO $ do+ so <- IO.hGetContents ro+ se <- IO.hGetContents re+ Conc.putMVar vo $! length so `seq` so+ Conc.putMVar ve $! length se `seq` se 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+ o <- Conc.takeMVar vo+ e <- Conc.takeMVar ve return (o, e, either Failure (const Success) res) -- | Lift a pure function to a computation over standard input/output.
Control/Shell/Internal.hs view
@@ -6,7 +6,7 @@ , shell, runSh , exit, run, try, getEnv, inEnv, unsafeLiftIO, (|>) ) where-import Control.Monad (when, ap)+import Control.Monad (when, ap, forM) import qualified Control.Concurrent as Conc import qualified Control.Exception as Ex import qualified System.Exit as Exit@@ -91,13 +91,12 @@ Ex.catch (Right <$> m) (\(Ex.SomeException e) -> pure $ Left (Failure (show e))) runSh env (Pipe p) = flip Ex.catch except $ do- ((stepenv, step) : steps) <- mkEnvs env p- ma <- waitPids =<< mapM (uncurry (runStep True)) steps- mb <- waitPids . (:[]) =<< runStep False stepenv step- case (ma, mb) of- (Failure err, _) -> pure $ Left (Failure err)- (_, Failure err) -> pure $ Left (Failure err)- _ -> pure $ Right ()+ steps <- mkEnvs env p+ pids <- mapM (uncurry (runStep True)) steps+ ma <- waitPids pids+ case ma of+ Failure err -> pure $ Left (Failure err)+ _ -> pure $ Right () where except = \(Ex.SomeException e) -> pure $ Left (Failure (show e)) runSh _ Done = do@@ -164,11 +163,12 @@ mkEnvs :: Env -> [PipeStep] -> IO [(Env, PipeStep)] mkEnvs env = go [] (envStdIn env) where+ go acc stdi [step] = do+ let env' = env {envStdIn = stdi, envStdOut = envStdOut env}+ pure ((env', step) : acc) go acc stdi (step : steps) = do (next, stdo) <- Proc.createPipe go ((env {envStdIn = stdi, envStdOut = stdo}, step):acc) next steps- go ((e, s) : steps) _ _ = do- pure ((e {envStdOut = envStdOut env}, s) : steps) go acc _ _ = pure acc -- | Terminate a pid, be it process or thread.
shellmate.cabal view
@@ -1,7 +1,7 @@ name: shellmate-version: 0.3.4.1+version: 0.3.4.2 synopsis: Simple interface for shell scripting in Haskell.-description: Aims to simplify development of cross-platform shell scripts and similar things.+description: Monadic EDSL for writing cross-platform shell scripts in Haskell. homepage: https://github.com/valderman/shellmate license: BSD3 license-file: LICENSE@@ -40,8 +40,8 @@ transformers >=0.3 && <0.6, bytestring >=0.10 && <0.11, filepath >=1.3 && <1.5,- process >=1.1 && <1.5,- directory >=1.1 && <1.3,+ process >=1.1 && <1.7,+ directory >=1.1 && <1.4, temporary >=1.1 && <1.3 default-language: Haskell2010