never executed always true always false
    1 {-# OPTIONS_GHC -Wall #-}
    2 {-# LANGUAGE FlexibleContexts #-}
    3 module Elm.Utils
    4     ( (|>), (<|), (>>)
    5     , run, unwrappedRun
    6     , CommandError(..)
    7     ) where
    8 
    9 import Prelude hiding ((>>))
   10 import Control.Monad.Except (MonadError, MonadIO, liftIO, throwError)
   11 import System.Exit (ExitCode(ExitSuccess, ExitFailure))
   12 import System.Process (readProcessWithExitCode)
   13 
   14 
   15 {-| Forward function application `x |> f == f x`. This function is useful
   16 for avoiding parenthesis and writing code in a more natural way.
   17 -}
   18 (|>) :: a -> (a -> b) -> b
   19 x |> f = f x
   20 
   21 
   22 {-| Backward function application `f <| x == f x`. This function is useful for
   23 avoiding parenthesis.
   24 -}
   25 (<|) :: (a -> b) -> a -> b
   26 f <| x = f x
   27 
   28 
   29 infixr 1 <|
   30 infixl 1 |>
   31 
   32 
   33 (>>) :: (a -> b) -> (b -> c) -> (a -> c)
   34 f >> g = \x -> f x |> g
   35 
   36 
   37 -- RUN EXECUTABLES
   38 
   39 data CommandError
   40     = MissingExe String
   41     | CommandFailed String String
   42 
   43 
   44 {-| Run a command, throw an error if the command is not found or if something
   45 goes wrong.
   46 -}
   47 run :: (MonadError String m, MonadIO m) => String -> [String] -> m String
   48 run command args =
   49   do  result <- liftIO (unwrappedRun command args)
   50       case result of
   51         Right out -> return out
   52         Left err ->
   53           throwError (context (message err))
   54   where
   55     context msg =
   56       "failure when running:" ++ concatMap (' ':) (command:args) ++ "\n" ++ msg
   57 
   58     message err =
   59       case err of
   60         CommandFailed stderr stdout ->
   61           stdout ++ stderr
   62         MissingExe msg ->
   63           msg
   64 
   65 
   66 unwrappedRun :: String -> [String] -> IO (Either CommandError String)
   67 unwrappedRun command args =
   68   do  (exitCode, stdout, stderr) <- readProcessWithExitCode command args ""
   69       return $
   70           case exitCode of
   71             ExitSuccess -> Right stdout
   72             ExitFailure code
   73                 | code == 127  -> Left (missingExe command)  -- UNIX
   74                 | code == 9009 -> Left (missingExe command)  -- Windows
   75                 | otherwise    -> Left (CommandFailed stdout stderr)
   76 
   77 
   78 missingExe :: String -> CommandError
   79 missingExe command =
   80   MissingExe $
   81     "Could not find command `" ++ command ++ "`. Do you have it installed?\n\
   82     \    Can it be run from anywhere? Is it on your PATH?"