feat(third_party/bazel): Check in rules_haskell from Tweag
This commit is contained in:
parent
2eb1dc26e4
commit
f723b8b878
479 changed files with 51484 additions and 0 deletions
20
third_party/bazel/rules_haskell/tools/coverage-reports/BUILD
vendored
Normal file
20
third_party/bazel/rules_haskell/tools/coverage-reports/BUILD
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
load(
|
||||
"@io_tweag_rules_haskell//haskell:haskell.bzl",
|
||||
"haskell_binary",
|
||||
)
|
||||
|
||||
haskell_binary(
|
||||
name = "coverage-report-renderer",
|
||||
srcs = ["Main.hs"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"@hackage//:MissingH",
|
||||
"@hackage//:base",
|
||||
"@hackage//:cmdargs",
|
||||
"@hackage//:directory",
|
||||
"@hackage//:filepath",
|
||||
"@hackage//:hxt",
|
||||
"@hackage//:hxt-xpath",
|
||||
"@hackage//:listsafe",
|
||||
],
|
||||
)
|
||||
134
third_party/bazel/rules_haskell/tools/coverage-reports/Main.hs
vendored
Normal file
134
third_party/bazel/rules_haskell/tools/coverage-reports/Main.hs
vendored
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
{-# LANGUAGE DeriveDataTypeable #-}
|
||||
{-# LANGUAGE NamedFieldPuns #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
|
||||
import Control.Monad (forM_)
|
||||
|
||||
import Control.Arrow.ListArrow (runLA)
|
||||
import Data.Either.Utils (maybeToEither)
|
||||
import Data.List (find)
|
||||
import Data.List.Safe (head, tail)
|
||||
import Data.List.Utils (split)
|
||||
import Data.Tree.NTree.TypeDefs (NTree(..))
|
||||
import Prelude hiding (head, tail)
|
||||
import System.Console.CmdArgs.Implicit (Data, Typeable, cmdArgs)
|
||||
import System.Directory (createDirectoryIfMissing)
|
||||
import System.Exit (exitFailure)
|
||||
import System.FilePath (FilePath, (</>), takeDirectory)
|
||||
import qualified Text.XML.HXT.Arrow.ReadDocument as XML
|
||||
import Text.XML.HXT.DOM.QualifiedName (localPart)
|
||||
import Text.XML.HXT.DOM.TypeDefs (XNode(..), XmlTree)
|
||||
import Text.XML.HXT.XPath.XPathEval (getXPath, getXPathSubTrees)
|
||||
|
||||
data Args = Args
|
||||
{ testlog :: FilePath
|
||||
, destdir :: FilePath
|
||||
} deriving (Data, Typeable)
|
||||
|
||||
data ReportFile = ReportFile
|
||||
{ content :: String
|
||||
, filename :: FilePath
|
||||
} deriving (Show)
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
Args {testlog, destdir} <- cmdArgs $ Args {testlog = "", destdir = ""}
|
||||
if testlog == ""
|
||||
then putStrLn noTestlogError >> exitFailure
|
||||
else do
|
||||
fileContents <- readFile testlog
|
||||
let xmlTrees = runLA XML.xreadDoc fileContents
|
||||
let rootTree = find isRoot xmlTrees
|
||||
case rootTree of
|
||||
Nothing -> do
|
||||
putStrLn "Invalid XML format for testlog."
|
||||
exitFailure
|
||||
Just tree -> do
|
||||
let reportFiles = generateReportFiles tree
|
||||
case reportFiles of
|
||||
Right reports ->
|
||||
forM_ reports $ \ReportFile {content, filename} -> do
|
||||
putStrLn $ concat ["Creating ", show $ destdir </> filename]
|
||||
createDirectoryIfMissing
|
||||
True
|
||||
(destdir </> takeDirectory filename)
|
||||
writeFile (destdir </> filename) content
|
||||
Left err -> do
|
||||
putStrLn err
|
||||
exitFailure
|
||||
|
||||
generateReportFiles :: XmlTree -> Either String [ReportFile]
|
||||
generateReportFiles doc =
|
||||
let testSuites = getXPath "/testsuites/testsuite" doc
|
||||
in concat <$> sequence (reportsForTestCase <$> testSuites)
|
||||
|
||||
reportsForTestCase :: XmlTree -> Either String [ReportFile]
|
||||
reportsForTestCase testSuite = do
|
||||
caseName <-
|
||||
extractAttr =<<
|
||||
maybeToEither
|
||||
"Couldn't find testcase name."
|
||||
(head (getXPathSubTrees "/testsuite/testcase/@name" testSuite))
|
||||
let coverageOutputDirectory = takeDirectory caseName
|
||||
testOutput <-
|
||||
extractText =<<
|
||||
maybeToEither
|
||||
"Couldn't find system output."
|
||||
(head (getXPathSubTrees "/testsuite/system-out" testSuite))
|
||||
htmlPortion <-
|
||||
maybeToEither
|
||||
("Couldn't find HTML report section in test case " ++ caseName ++ ".")
|
||||
(head =<< tail (split testOutputSeparator testOutput))
|
||||
let coverageReportPartXmlTrees = runLA XML.hreadDoc htmlPortion
|
||||
traverse
|
||||
(coveragePartToReportFile coverageOutputDirectory)
|
||||
coverageReportPartXmlTrees
|
||||
|
||||
coveragePartToReportFile :: FilePath -> XmlTree -> Either String ReportFile
|
||||
coveragePartToReportFile parentDirectory reportPart = do
|
||||
filename <-
|
||||
extractAttr =<<
|
||||
maybeToEither
|
||||
"Couldn't find report part name."
|
||||
(head (getXPathSubTrees "/coverage-report-part/@name" reportPart))
|
||||
content <- extractText reportPart
|
||||
return $
|
||||
ReportFile
|
||||
{ content = content
|
||||
, filename = "coverage-reports" </> parentDirectory </> filename
|
||||
}
|
||||
|
||||
noTestlogError :: String
|
||||
noTestlogError =
|
||||
unlines
|
||||
[ "ERROR: You must specify the testlog XML file location with --testlog."
|
||||
, "It is found inside the bazel-testlog, in the respective"
|
||||
, "folder for the test you're interested in."
|
||||
, "This must be after having run 'bazel coverage'."
|
||||
]
|
||||
|
||||
isRoot :: XmlTree -> Bool
|
||||
isRoot tree =
|
||||
case tree of
|
||||
NTree (XTag name _) _ -> localPart name == "testsuites"
|
||||
_ -> False
|
||||
|
||||
extractAttr :: XmlTree -> Either String String
|
||||
extractAttr tree =
|
||||
case tree of
|
||||
NTree (XAttr _) [NTree (XText value) []] -> pure value
|
||||
_ -> Left "Couldn't extract attribute from test XML."
|
||||
|
||||
extractText :: XmlTree -> Either String String
|
||||
extractText tree =
|
||||
let treeToText :: XmlTree -> String -> String
|
||||
treeToText textTree acc =
|
||||
case textTree of
|
||||
(NTree (XText value) _) -> acc ++ value
|
||||
_ -> ""
|
||||
in case tree of
|
||||
NTree (XTag _ _) textTree -> pure $ foldr treeToText "" textTree
|
||||
_ -> Left "Couldn't extract text from test XML."
|
||||
|
||||
testOutputSeparator :: String
|
||||
testOutputSeparator = "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
|
||||
Loading…
Add table
Add a link
Reference in a new issue