git-fmt-0.3.1.0: src/Omnifmt/Process.hs
{-|
Module : Omnifmt.Process
Description : System process utilities.
Copyright : (c) Henry J. Wylde, 2015
License : BSD3
Maintainer : public@hjwylde.com
System process utilities.
-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Omnifmt.Process (
-- * Run
runProcess, runProcess_, runTimedProcess, runCommand, runCommand_, runTimedCommand,
runCreateProcess, runCreateProcess_,
) where
import Control.Monad.Except
import Control.Monad.Logger
import Data.Text hiding (unwords)
import Omnifmt.Exit
import System.Exit
import System.Process.Extra (CmdSpec (..), CreateProcess)
import qualified System.Process.Extra as System
-- | Runs the given executable with the arguments.
-- Returns the exit code, stdout and stderr.
runProcess :: (MonadIO m, MonadLogger m) => FilePath -> [String] -> m (ExitCode, String, String)
runProcess cmd args = runCreateProcess (System.proc cmd args) ""
-- | Runs the given executable with the arguments.
-- Depending on the exit code, either logs the stderr and exits fast (128) or returns the stdout.
runProcess_ :: (MonadError ExitCode m, MonadIO m, MonadLogger m) => FilePath -> [String] -> m String
runProcess_ cmd args = runCreateProcess_ (System.proc cmd args) ""
-- | Runs the given executable with the arguments.
-- Returns the exit code, stdout and stderr.
-- The command is wrapped in a `timeout -k N*2 N` call.
runTimedProcess :: (MonadIO m, MonadLogger m) => Int -> FilePath -> [String] -> m (ExitCode, String, String)
runTimedProcess n cmd args = runCreateProcess (System.proc "timeout" $ "-k":show (n * 2):show n:cmd:args) ""
-- | Runs the given command.
-- Returns the exit code, stdout and stderr.
runCommand :: (MonadIO m, MonadLogger m) => String -> m (ExitCode, String, String)
runCommand cmd = runCreateProcess (System.shell cmd) ""
-- | Runs the given command.
-- Depending on the exit code, either logs the stderr and exits fast (128) or returns the stdout.
runCommand_ :: (MonadError ExitCode m, MonadIO m, MonadLogger m) => String -> m String
runCommand_ cmd = runCreateProcess_ (System.shell cmd) ""
-- | Runs the given command.
-- Returns the exit code, stdout and stderr.
-- The command is wrapped in a `timeout -k N*2 N` call.
runTimedCommand :: (MonadIO m, MonadLogger m) => Int -> String -> m (ExitCode, String, String)
runTimedCommand n cmd = runCreateProcess (System.shell $ unwords ["timeout -k", show $ n * 2, show n, cmd]) ""
-- | Runs the given 'CreateProcess'.
-- Returns the exit code, stdout and stderr.
runCreateProcess :: (MonadIO m, MonadLogger m) => CreateProcess -> String -> m (ExitCode, String, String)
runCreateProcess process stdin = do
logDebugN $ pack (case System.cmdspec process of
ShellCommand cmd -> cmd
RawCommand cmd args -> unwords (cmd:args)
)
liftIO $ System.readCreateProcessWithExitCode process stdin
-- | Runs the given 'CreateProcess'.
-- Depending on the exit code, either logs the stderr and exits fast (128) or returns the stdout.
runCreateProcess_ :: (MonadError ExitCode m, MonadIO m, MonadLogger m) => CreateProcess -> String -> m String
runCreateProcess_ process stdin = do
(exitCode, stdout, stderr) <- runCreateProcess process stdin
if exitCode == ExitSuccess
then return stdout
else panic stderr