packages feed

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]"