module Main where import Data.List (intercalate) import System.Exit (ExitCode(..), exitFailure, exitSuccess, exitWith) import System.Directory (doesDirectoryExist, doesFileExist, getCurrentDirectory, setCurrentDirectory, getDirectoryContents) import System.FilePath (()) import System.Process (readProcessWithExitCode, callProcess) import System.IO (hPutStrLn, hPrint, stderr) import Control.Monad (filterM, liftM, when) testDirs :: [String] testDirs = ["test/harness","harness","."] getActualTestDirectory :: [String] -> IO FilePath getActualTestDirectory test_dirs = do validDirs <- filterM (doesFileExist . ( "run-harness.hs")) test_dirs case validDirs of [] -> ioError (userError ("run-harness.hs not found in " ++ intercalate " or " test_dirs)) (d:_) -> return d subdirectoriesOf :: FilePath -> IO [FilePath] subdirectoriesOf fp = do entries <- getDirectoryContents fp filterM (doesDirectoryExist . (fp )) (filter (not . isSpecialDir) entries) where isSpecialDir "." = True isSpecialDir ".." = True isSpecialDir _ = False -- from Control.Monad.Extra findM :: Monad m => (a -> m Bool) -> [a] -> m (Maybe a) findM _ [] = return Nothing findM p (x:xs) = do guard <- p x ; if guard then (return $ Just x) else (findM p xs) main :: IO ExitCode main = do actual_test_dir <- getActualTestDirectory testDirs has_makefile <- doesFileExist (actual_test_dir "Makefile") when (not has_makefile) $ do hPutStrLn stderr "No Makefile found (out of source tree)" hPutStrLn stderr "Skipping harness test" exitWith ExitSuccess tests <- subdirectoriesOf actual_test_dir cdir <- getCurrentDirectory hPutStrLn stderr ("Changing to test directory " ++ actual_test_dir ++ " and compiling") -- build test executables setCurrentDirectory (cdiractual_test_dir) callProcess "make" ["prepare"] -- run harness tests hasFailure <- findM (liftM (/= ExitSuccess) . runTest . (cdir) . (actual_test_dir)) tests setCurrentDirectory cdir case hasFailure of Nothing -> exitSuccess Just _failed -> exitFailure where runTest :: FilePath -> IO ExitCode runTest dir = do setCurrentDirectory dir (exitCode, _outp, _errp) <- readProcessWithExitCode "make" [] "" hPutStrLn stderr ("cd " ++ dir ++ " && make: " ++ show exitCode) when (exitCode /= ExitSuccess) $ do hPutStrLn stderr "=== Standard Output ===" hPutStrLn stderr _outp hPutStrLn stderr "=== Error Output ===" hPutStrLn stderr _errp hPutStrLn stderr "=== End of Output ===" return exitCode