codecov-haskell-0.1.0: src/RunCabalTestMain.hs
module Main where
import Control.Concurrent.Async (Async, async, waitBoth)
import Control.Monad
import Data.List
import Data.List.Split
import GHC.IO.Handle
import System.IO (hPutStrLn, stdout, stderr)
import System.Exit (exitFailure, exitSuccess)
import System.Environment (getArgs)
import System.Process
import Text.Regex.Posix
defaultCabalName :: String
defaultCabalName = "cabal"
isTestFailure :: String -> Bool
isTestFailure line = line =~ "^Test suite .*: FAIL$"
readLines :: Handle -> Handle -> IO [String]
readLines hIn hOut = do
isEOF <- hIsEOF hIn
if isEOF
then return []
else do
x <- hGetLine hIn
hPutStrLn hOut x
xs <- readLines hIn hOut
return (x : xs)
checkFailure :: Handle -> Handle -> IO (Async Bool)
checkFailure hIn = async . liftM (not . any isTestFailure) . readLines hIn
runCabalTest :: String -> [String] -> IO Bool
runCabalTest cabalName args = do
(_, out, err, _) <- runInteractiveCommand (cabalName ++ " test " ++ unwords args)
aOutResult <- checkFailure out stdout
aErrResult <- checkFailure err stderr
results <- waitBoth aOutResult aErrResult
return $ uncurry (&&) results
getCabalName :: [String] -> Maybe String
getCabalName [] = Just defaultCabalName
getCabalName [arg] = case splitOn "=" arg of
(_ : cabalName : _) -> Just cabalName
_ -> Nothing
getCabalName _ = Nothing
main :: IO ()
main = do
cmdArgs <- getArgs
case cmdArgs of
["--help"] -> usage >> exitSuccess
["-h"] -> usage >> exitSuccess
options -> case mCabalName of
Just cabalName -> do
result <- runCabalTest cabalName cabalTestArgs
if result then exitSuccess else exitFailure
Nothing -> usage >> exitFailure
where (runCabalTestArgs, cabalTestArgs) = partition (=~ "^--cabal-name=.*") options
mCabalName = getCabalName runCabalTestArgs
where usage = putStrLn "Usage: run-cabal-test [run-cabal-test-options] [cabal-test-options]"