{-# LANGUAGE ViewPatterns #-} module Main where -- Static site generator for failing tests import Data.Algorithm.Diff (getGroupedDiff) import Data.Algorithm.DiffOutput (ppDiff) import System.Directory import System.FilePath import Test.CommonUtils import Control.Monad import Debug.Trace import Data.List import System.Environment import Data.Maybe import Text.Read main :: IO () main = do createDirectoryIfMissing True failuresHtmlDir n <- getArgs case readMaybe =<< listToMaybe n of Nothing -> site 100 Just k -> site k site :: Int -> IO () site n = do putStrLn $ "Generating site for first: " ++ show n failPaths <- filterM doesFileExist =<< (map (failuresDir ) . take n <$> getDirectoryContents failuresDir) traceShowM failPaths fails <- mapM parseFail failPaths writeFile origFailuresFile (intercalate "\n" (map getfname fails)) -- writeFile "failures/failures.html" (makeIndex failPaths) writeFile (failuresHtmlDir failuresHtmlFile) (makeIndex failPaths) let padded = failuresHtmlFile : (map makeFailLink failPaths ++ [failuresHtmlFile]) let resolved = zipWith (\x (y,z) -> (x, y, z)) padded (zip (tail padded) (tail (tail padded))) mapM_ (uncurry page) (zip resolved fails) makeFailLink :: FilePath -> String makeFailLink fp = takeFileName fp <.> "html" makeIndex :: [FilePath] -> String makeIndex files = intercalate "
" (map mkIndexLink files) where mkIndexLink f = mkLink (takeFileName f <.> "html") f page :: (FilePath, FilePath, FilePath) -> Failure -> IO () page (prev, out, next) (Failure res fname) = do -- traceM out original <- readFile fname let lres = lines res let maxLines = 50000 let diff = getGroupedDiff (lines original) (take maxLines lres) let l = length lres if (l > maxLines) then do -- putStrLn ("Skipping: " ++ fname) >> print l let resTrunc = (intercalate "\n" $ take maxLines lres) ++ "\n*****************TRUNCATED*******" writeFile (failuresHtmlDir out) (mkPage fname (ppDiff diff) prev next original resTrunc) else -- writeFile ("failures" out) (mkPage (ppDiff diff) prev next original res) writeFile (failuresHtmlDir out) (mkPage fname (ppDiff diff) prev next original res) mkPage :: FilePath -> String -> String -> String -> String -> String -> String mkPage filename diff prev next original printed = intercalate "
" [mkLink prev "prev" , mkLink failuresHtmlFile "home" , mkLink next "next" , "" , "
" ++ filename ++ "
" , "" , "
" ++ diff ++ "
" , "

original

" , "
" ++ original ++ "
" , "

printed

" , "
" ++ printed ++ "
" ] mkLink :: String -> String -> String mkLink s label = "" ++ label ++ "" data Failure = Failure String FilePath getfname :: Failure -> FilePath getfname (Failure _ fp) = fp parseFail :: FilePath -> IO Failure parseFail fp = do res <- lines <$> readFile fp let (finalres, head . tail -> fname) = break (=="==============") res return (Failure (unlines finalres) fname)