content: {-# LANGUAGE TupleSections, ConstraintKinds #-}
  
  -- | Extra functions for creating processes. Specifically variants that automatically check
  --   the 'ExitCode' and capture the 'stdout' \/ 'stderr' handles.
  module System.Process.Extra(
      module System.Process,
      system_, systemOutput, systemOutput_
      ) where
  
  import Control.Monad
  import System.IO.Extra
  import System.Process
  import System.Exit
  import Data.Functor
  import Partial
  import Prelude
  
  
  -- | A version of 'system' that also captures the output, both 'stdout' and 'stderr'.
  --   Returns a pair of the 'ExitCode' and the output.
  systemOutput :: String -> IO (ExitCode, String)
  systemOutput x = withTempFile $ \file -> do
      exit <- withFile file WriteMode $ \h -> do
          (_, _, _, pid) <- createProcess (shell x){std_out=UseHandle h, std_err=UseHandle h}
          waitForProcess pid
      (exit,) <$> readFile' file
  
  
  -- | A version of 'system' that throws an error if the 'ExitCode' is not 'ExitSuccess'.
  system_ :: Partial => String -> IO ()
  system_ x = do
      res <- system x
      when (res /= ExitSuccess) $
          error $ "Failed when running system command: " ++ x
  
  -- | A version of 'system' that captures the output (both 'stdout' and 'stderr')
  --   and throws an error if the 'ExitCode' is not 'ExitSuccess'.
  systemOutput_ :: Partial => String -> IO String
  systemOutput_ x = do
      (res,out) <- systemOutput x
      when (res /= ExitSuccess) $
          error $ "Failed when running system command: " ++ x
      pure out
  