-- |
-- Module:     Trace.Hpc.Codecov.Report
-- Copyright:  (c) 2022 8c6794b6
-- License:    BSD3
-- Maintainer: 8c6794b6 <8c6794b6@gmail.com>
--
-- Generate Codecov report data.

module Trace.Hpc.Codecov.Report
  ( -- * Types
    Report(..)
  , CoverageEntry(..)
  , Format(..)
  , LineHits
  , Hit(..)
  , FunctionHits
  , BranchHits

    -- * Functions
  , genReport
  , genCoverageEntries
  , emitCoverage
  ) where

-- base
import Control.Monad                  (when)
import System.IO                      (IOMode (..), hPutStrLn, stderr,
                                       stdout, withFile)

-- bytestring
import Data.ByteString.Builder        (hPutBuilder)

-- Internal
import Trace.Hpc.Codecov.Report.Emit
import Trace.Hpc.Codecov.Report.Entry


-- ------------------------------------------------------------------------
--
-- Exported
--
-- ------------------------------------------------------------------------

-- | Generate report data from options.
genReport :: Report -> IO ()
genReport :: Report -> IO ()
genReport Report
rpt = do
  let mb_out :: Maybe FilePath
mb_out = Report -> Maybe FilePath
reportOutFile Report
rpt
      oname :: FilePath
oname = forall b a. b -> (a -> b) -> Maybe a -> b
maybe FilePath
"stdout" forall a. Show a => a -> FilePath
show Maybe FilePath
mb_out
      say :: FilePath -> IO ()
say = forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Report -> Bool
reportVerbose Report
rpt) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> FilePath -> IO ()
hPutStrLn Handle
stderr
  [CoverageEntry]
entries <- Report -> IO [CoverageEntry]
genCoverageEntries Report
rpt
  FilePath -> IO ()
say (FilePath
"Writing report to " forall a. [a] -> [a] -> [a]
++ FilePath
oname)
  Format -> Maybe FilePath -> [CoverageEntry] -> IO ()
emitCoverage (Report -> Format
reportFormat Report
rpt) Maybe FilePath
mb_out [CoverageEntry]
entries
  FilePath -> IO ()
say FilePath
"Done"

-- | Generate test coverage entries.
genCoverageEntries :: Report -> IO [CoverageEntry]
genCoverageEntries :: Report -> IO [CoverageEntry]
genCoverageEntries Report
rpt = Report -> FilePath -> IO Tix
readTixFile Report
rpt (Report -> FilePath
reportTix Report
rpt) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Report -> Tix -> IO [CoverageEntry]
tixToCoverage Report
rpt

-- | Emit simple coverage data.
emitCoverage
  :: Format
  -- ^ Format of the report.
  --
  -- @since 0.4.0.0
  -> Maybe FilePath
  -- ^ 'Just' output file name, or 'Nothing' for 'stdout'.
  -> [CoverageEntry]
  -- ^ Coverage entries to write.
  -> IO ()
emitCoverage :: Format -> Maybe FilePath -> [CoverageEntry] -> IO ()
emitCoverage Format
fmt Maybe FilePath
mb_outfile [CoverageEntry]
entries = forall {r}. (Handle -> IO r) -> IO r
wrap Handle -> IO ()
emit
  where
    wrap :: (Handle -> IO r) -> IO r
wrap = forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall a b. (a -> b) -> a -> b
$ Handle
stdout) (forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
`withFile` IOMode
WriteMode) Maybe FilePath
mb_outfile
    emit :: Handle -> IO ()
emit = forall a b c. (a -> b -> c) -> b -> a -> c
flip Handle -> Builder -> IO ()
hPutBuilder ([CoverageEntry] -> Builder
builder [CoverageEntry]
entries)
    builder :: [CoverageEntry] -> Builder
builder = case Format
fmt of
      Format
Codecov   -> [CoverageEntry] -> Builder
buildCodecov
      Format
Lcov      -> [CoverageEntry] -> Builder
buildLcov
      Format
Cobertura -> [CoverageEntry] -> Builder
buildCobertura