packages feed

hpc-coveralls 0.3.0 → 0.4.0

raw patch · 15 files changed

+249/−164 lines, 15 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- HpcCoverallsCmdLine: CmdMain :: [String] -> [String] -> Bool -> HpcCoverallsArgs
- HpcCoverallsCmdLine: data HpcCoverallsArgs
- HpcCoverallsCmdLine: displayReport :: HpcCoverallsArgs -> Bool
- HpcCoverallsCmdLine: excludeDirs :: HpcCoverallsArgs -> [String]
- HpcCoverallsCmdLine: hpcCoverallsArgs :: HpcCoverallsArgs
- HpcCoverallsCmdLine: instance Data HpcCoverallsArgs
- HpcCoverallsCmdLine: instance Show HpcCoverallsArgs
- HpcCoverallsCmdLine: instance Typeable HpcCoverallsArgs
- HpcCoverallsCmdLine: testSuites :: HpcCoverallsArgs -> [String]
- Trace.Hpc.Coveralls.Config: Config :: [String] -> [FilePath] -> Config
- Trace.Hpc.Coveralls.Config: data Config
- Trace.Hpc.Coveralls.Config: excludedDirs :: Config -> [FilePath]
- Trace.Hpc.Coveralls.Config: testSuites :: Config -> [String]
- Trace.Hpc.Coveralls.Curl: PostFailure :: String -> PostResult
- Trace.Hpc.Coveralls.Curl: PostSuccess :: URLString -> PostResult
- Trace.Hpc.Coveralls.Curl: data PostResult
- Trace.Hpc.Coveralls.Curl: postJson :: String -> URLString -> IO PostResult
- Trace.Hpc.Coveralls.Types: type CoverageEntry = Value
- Trace.Hpc.Coveralls.Types: type ModuleCoverageData = (String, Mix, [Integer])
- Trace.Hpc.Coveralls.Types: type SimpleCoverage = [CoverageEntry]
- Trace.Hpc.Coveralls.Types: type TestSuiteCoverageData = Map FilePath ModuleCoverageData
- Trace.Hpc.Lix: Full :: Hit
- Trace.Hpc.Lix: Irrelevant :: Hit
- Trace.Hpc.Lix: None :: Hit
- Trace.Hpc.Lix: Partial :: Hit
- Trace.Hpc.Lix: data Hit
- Trace.Hpc.Lix: getLine :: MixEntry -> Int
- Trace.Hpc.Lix: groupByIndex :: Int -> [(Int, a)] -> [[a]]
- Trace.Hpc.Lix: instance Eq Hit
- Trace.Hpc.Lix: instance Show Hit
- Trace.Hpc.Lix: toHit :: [Bool] -> Hit
- Trace.Hpc.Lix: toLineHit :: (MixEntry, Integer) -> (Int, Bool)
- Trace.Hpc.Lix: toLix :: Int -> [(MixEntry, Integer)] -> Lix
- Trace.Hpc.Lix: type Lix = [Hit]
- Trace.Hpc.Paths: hpcDir :: FilePath
- Trace.Hpc.Paths: mixDir :: FilePath
- Trace.Hpc.Paths: tixDir :: FilePath
+ Trace.Hpc.Coveralls.Lix: getLine :: MixEntry -> Int
+ Trace.Hpc.Coveralls.Lix: toHit :: [Bool] -> Hit
+ Trace.Hpc.Coveralls.Lix: toLineHit :: (MixEntry, Integer) -> (Int, Bool)
+ Trace.Hpc.Coveralls.Lix: toLix :: Int -> [(MixEntry, Integer)] -> Lix
+ Trace.Hpc.Coveralls.Types: AllowPartialLines :: CoverageMode
+ Trace.Hpc.Coveralls.Types: Full :: Hit
+ Trace.Hpc.Coveralls.Types: Irrelevant :: Hit
+ Trace.Hpc.Coveralls.Types: None :: Hit
+ Trace.Hpc.Coveralls.Types: Partial :: Hit
+ Trace.Hpc.Coveralls.Types: PostFailure :: String -> PostResult
+ Trace.Hpc.Coveralls.Types: PostSuccess :: URLString -> PostResult
+ Trace.Hpc.Coveralls.Types: StrictlyFullLines :: CoverageMode
+ Trace.Hpc.Coveralls.Types: data CoverageMode
+ Trace.Hpc.Coveralls.Types: data Hit
+ Trace.Hpc.Coveralls.Types: data PostResult
+ Trace.Hpc.Coveralls.Types: instance Data CoverageMode
+ Trace.Hpc.Coveralls.Types: instance Default CoverageMode
+ Trace.Hpc.Coveralls.Types: instance Eq CoverageMode
+ Trace.Hpc.Coveralls.Types: instance Eq Hit
+ Trace.Hpc.Coveralls.Types: instance Show CoverageMode
+ Trace.Hpc.Coveralls.Types: instance Show Hit
+ Trace.Hpc.Coveralls.Types: instance Typeable CoverageMode
+ Trace.Hpc.Coveralls.Types: type Lix = [Hit]
+ Trace.Hpc.Coveralls.Util: fst4 :: (a, b, c, d) -> a
+ Trace.Hpc.Coveralls.Util: groupByIndex :: Int -> [(Int, a)] -> [[a]]
+ Trace.Hpc.Coveralls.Util: matchAny :: [String] -> String -> Bool
+ Trace.Hpc.Coveralls.Util: toFirstAndRest :: (a, b, c, d) -> (a, (b, c, d))

Files

CHANGELOG.md view
@@ -1,3 +1,8 @@+[0.4.0](https://github.com/guillaume-nargeot/hpc-coveralls/issues?milestone=5&state=closed)+-----+* Add option to configure the coverage data conversion (issue #15)+* Add option to prevent from sending the coverage report (issue #17)+ [0.3.0](https://github.com/guillaume-nargeot/hpc-coveralls/issues?milestone=4&state=closed) ----- * Support setting multiple test suites (issue #14)
README.md view
@@ -41,8 +41,12 @@  When using hpc 0.6, `cabal test` outputs an error message and exits with the error code `1`, which results in a build failure. -In order to prevent this from happening, hpc-coveralls provides the `run-cabal-test` command which runs `cabal test` and returns with `0` if the regex `^Test suite .*: FAIL$` never matches any line of the output.+In order to prevent this from happening, hpc-coveralls provides the `run-cabal-test` command which runs `cabal test` and returns with `0` if the following regex never matches any line of the output: +```perl+/^Test suite .*: FAIL$/+```+ As this issue is fixed in the hpc version shipped with GHC 7.8, you don't have to use `run-cabal-test` when testing with GHC 7.8 and can safely use `cabal test`.  ### Options@@ -66,7 +70,9 @@  ### Options -The `--exclude-dir` option can be used to exclude source files located under a given directory from the coverage report.<br/>+#### --exclude-dir++The `--exclude-dir` option allows to exclude source files located under a given directory from the coverage report.<br/> You can exclude source files located under the `test/` by using this option as in the following example:  ```yaml@@ -79,22 +85,38 @@ hpc-coveralls --exclude-dir=test1 --exclude-dir=test2 [test-suite-names] ``` -# Limitations+#### --coverage-mode -As Coveralls doesn't support yet partial-line coverage, the following convention is used to represent line coverage with line hit counts:+As Coveralls doesn't support partial-line coverage yet, hpc-coveralls currently converts hpc coverage data into line based coverage data, which is the only format supported at the moment.+The `--coverage-mode` option allows to configure how the coverage data is converted into Coveralls format, based on your needs.<br/>+Below are the two modes currently available, with an explanation of what the hit count values mean.++`--coverage-mode=AllowPartialLines` (default): - `0` : the line is never hit, - `1` : the line is partially covered, - `2` : the line is fully covered. -This convention is the same as the one used by [cloverage](https://github.com/lshift/cloverage) coveralls output for Clojure projects code coverage.+Note that `AllowPartialLines` conversion mode follows the same convention as the one used by [cloverage](https://github.com/lshift/cloverage) coveralls output for Clojure projects code coverage. -There's an [open issue](https://github.com/lemurheavy/coveralls-public/issues/216) to improve this.+`--coverage-mode=StrictlyFullLines`:+- `0` : the line is never hit or only partially covered,+- `1` : the line is fully covered. +Please also note that there is an [open issue](https://github.com/lemurheavy/coveralls-public/issues/216) on coveralls issue tracker in order to improve this (add support for partial line coverage).++#### --dont-send++The `--dont-send` option prevents hpc-coveralls from sending the coverage report to coveralls.io.+This option can be used together with `--display-report` for testing purpose.<br/>+For example, you can try various combinations of the other options and confirm the difference in the resulting report outputs.+ # Contributing  hpc-coveralls is still under development and any contributions are welcome!  [Future Plans and Ideas](https://github.com/guillaume-nargeot/hpc-coveralls/wiki/Future-Plans-and-Ideas)++Please share your comments and suggestions on hpc-coveralls [Gitter channel](https://gitter.im/guillaume-nargeot/hpc-coveralls)!  # License 
hpc-coveralls.cabal view
@@ -1,5 +1,5 @@ name:           hpc-coveralls-version:        0.3.0+version:        0.4.0 synopsis:       Coveralls.io support for Haskell. description:   This utility converts and sends Haskell projects hpc code coverage to@@ -42,13 +42,15 @@ library   hs-source-dirs: src   exposed-modules:-    HpcCoverallsCmdLine,     Trace.Hpc.Coveralls,+    Trace.Hpc.Coveralls.Lix,+    Trace.Hpc.Coveralls.Types,+    Trace.Hpc.Coveralls.Util+  other-modules:+    HpcCoverallsCmdLine,     Trace.Hpc.Coveralls.Config,     Trace.Hpc.Coveralls.Curl,-    Trace.Hpc.Coveralls.Types,-    Trace.Hpc.Paths,-    Trace.Hpc.Lix+    Trace.Hpc.Coveralls.Paths   build-depends:     aeson,     base < 5,@@ -69,7 +71,7 @@     cmdargs >= 0.10,     curl >= 1.3.8,     hpc >= 0.6.0.0-  ghc-options:   -Wall -fwarn-tabs+  ghc-options:    -Wall -fwarn-tabs -fwarn-incomplete-uni-patterns  executable run-cabal-test   hs-source-dirs: src@@ -80,7 +82,7 @@     process,     regex-posix,     split-  ghc-options:    -Wall -fwarn-tabs+  ghc-options:    -Wall -fwarn-tabs -fwarn-incomplete-uni-patterns  test-suite test-all   hs-source-dirs: test
src/HpcCoverallsCmdLine.hs view
@@ -6,17 +6,22 @@ import Data.Version (Version(..)) import Paths_hpc_coveralls (version) import System.Console.CmdArgs+import Trace.Hpc.Coveralls.Types  data HpcCoverallsArgs = CmdMain     { excludeDirs   :: [String]     , testSuites    :: [String]     , displayReport :: Bool+    , dontSend      :: Bool+    , coverageMode  :: CoverageMode     } deriving (Data, Show, Typeable)  hpcCoverallsArgs :: HpcCoverallsArgs hpcCoverallsArgs = CmdMain-    { excludeDirs   = []    &= explicit &= typDir &= name "exclude-dir"    &= help "Exclude sources files under the matching directory from the coverage report send to coveralls.io"-    , displayReport = False &= explicit           &= name "display-report" &= help "Display the json code coverage report that will be sent to coveralls.io"+    { excludeDirs   = []                &= explicit &= typDir     &= name "exclude-dir"    &= help "Exclude sources files under the matching directory from the coverage report"+    , displayReport = False             &= explicit               &= name "display-report" &= help "Display the json code coverage report that will be sent to coveralls.io"+    , dontSend      = False             &= explicit               &= name "dont-send"      &= help "Do not send the report to coveralls.io"+    , coverageMode  = AllowPartialLines &= explicit &= typ "MODE" &= name "coverage-mode"  &= help "Coverage conversion mode: AllowPartialLines (default), StrictlyFullLines"     , testSuites    = []                &= typ "TEST-SUITE" &= args     } &= summary ("hpc-coveralls-" ++ versionString version ++ ", (C) Guillaume Nargeot 2014")       &= program "hpc-coveralls"
src/HpcCoverallsMain.hs view
@@ -1,5 +1,6 @@ module Main where +import Control.Applicative import Control.Monad import Data.Aeson import qualified Data.ByteString.Lazy.Char8 as BSL@@ -19,7 +20,7 @@ getServiceAndJobID :: IO (String, String) getServiceAndJobID = do     env <- getEnvironment-    case fmap snd $ find (isJust . flip lookup env . fst) ciEnvVars of+    case snd <$> find (isJust . flip lookup env . fst) ciEnvVars of         Just (ciName, jobIdVarName) -> do             jobId <- getEnv jobIdVarName             return (ciName, jobId)@@ -34,23 +35,24 @@ writeJson :: String -> Value -> IO () writeJson filePath = BSL.writeFile filePath . encode -toConfig :: HpcCoverallsArgs -> Maybe Config-toConfig hca = case testSuites hca of+getConfig :: HpcCoverallsArgs -> Maybe Config+getConfig hca = case testSuites hca of     []             -> Nothing-    testSuiteNames -> Just $ Config testSuiteNames (excludeDirs hca)+    testSuiteNames -> Just $ Config testSuiteNames (excludeDirs hca) (coverageMode hca)  main :: IO () main = do     hca <- cmdArgs hpcCoverallsArgs-    case toConfig hca of+    case getConfig hca of         Nothing -> putStrLn "Please specify a target test suite name" >> exitSuccess         Just config -> do             (serviceName, jobId) <- getServiceAndJobID             coverallsJson <- generateCoverallsFromTix serviceName jobId config-            let filePath = serviceName ++ "-" ++ jobId ++ ".json"             when (displayReport hca) $ BSL.putStrLn $ encode coverallsJson+            let filePath = serviceName ++ "-" ++ jobId ++ ".json"             writeJson filePath coverallsJson-            response <- postJson filePath urlApiV1-            case response of-                PostSuccess url -> putStrLn ("URL: " ++ url) >> exitSuccess-                PostFailure msg -> putStrLn ("Error: " ++ msg) >> exitFailure+            unless (dontSend hca) $ do+                response <- postJson filePath urlApiV1+                case response of+                    PostSuccess url -> putStrLn ("URL: " ++ url) >> exitSuccess+                    PostFailure msg -> putStrLn ("Error: " ++ msg) >> exitFailure
src/Trace/Hpc/Coveralls.hs view
@@ -7,57 +7,71 @@ -- Maintainer:  Guillaume Nargeot <guillaume+hackage@nargeot.com> -- Stability:   experimental ----- Types and functions for converting and sending hpc output to coveralls.io.+-- Functions for converting and sending hpc output to coveralls.io.  module Trace.Hpc.Coveralls ( generateCoverallsFromTix ) where -import Data.Aeson-import Data.Aeson.Types ()-import Data.List+import           Data.Aeson+import           Data.Aeson.Types ()+import           Data.List import qualified Data.Map.Strict as M-import System.Exit (exitFailure)-import Trace.Hpc.Coveralls.Config-import Trace.Hpc.Coveralls.Types-import Trace.Hpc.Lix-import Trace.Hpc.Mix-import Trace.Hpc.Paths-import Trace.Hpc.Tix+import           System.Exit (exitFailure)+import           Trace.Hpc.Coveralls.Config+import           Trace.Hpc.Coveralls.Lix+import           Trace.Hpc.Coveralls.Paths+import           Trace.Hpc.Coveralls.Types+import           Trace.Hpc.Coveralls.Util+import           Trace.Hpc.Mix+import           Trace.Hpc.Tix -lixToSimpleCoverage :: Lix -> SimpleCoverage-lixToSimpleCoverage = map conv-    where conv Full    = Number 2-          conv Partial = Number 1-          conv None    = Number 0-          conv Irrelevant = Null+type ModuleCoverageData = (+    String,    -- file source code+    Mix,       -- module index data+    [Integer]) -- tixs recorded by hpc -toSimpleCoverage :: Int -> [(MixEntry, Integer)] -> SimpleCoverage-toSimpleCoverage lineCount = lixToSimpleCoverage . toLix lineCount+type TestSuiteCoverageData = M.Map FilePath ModuleCoverageData -coverageToJson :: FilePath -> ModuleCoverageData -> Value-coverageToJson filePath (source, mix, tixs) = object [+-- single file coverage data in the format defined by coveralls.io+type SimpleCoverage = [CoverageEntry]++-- Is there a way to restrict this to only Number and Null?+type CoverageEntry = Value++type LixConverter = Lix -> SimpleCoverage++strictConverter :: LixConverter+strictConverter = map $ \lix -> case lix of+    Full       -> Number 1+    Partial    -> Number 0+    None       -> Number 0+    Irrelevant -> Null++looseConverter :: LixConverter+looseConverter = map $ \lix -> case lix of+    Full       -> Number 2+    Partial    -> Number 1+    None       -> Number 0+    Irrelevant -> Null++toSimpleCoverage :: LixConverter -> Int -> [(MixEntry, Integer)] -> SimpleCoverage+toSimpleCoverage convert lineCount = convert . toLix lineCount++coverageToJson :: LixConverter -> FilePath -> ModuleCoverageData -> Value+coverageToJson converter filePath (source, mix, tixs) = object [     "name" .= filePath,     "source" .= source,     "coverage" .= coverage]-    where coverage = toSimpleCoverage lineCount mixEntryTixs+    where coverage = toSimpleCoverage converter lineCount mixEntryTixs           lineCount = length $ lines source           mixEntryTixs = zip (getMixEntries mix) tixs           getMixEntries (Mix _ _ _ _ mixEntries) = mixEntries -toCoverallsJson :: String -> String -> TestSuiteCoverageData -> Value-toCoverallsJson serviceName jobId testSuiteCoverageData = object [+toCoverallsJson :: String -> String -> LixConverter -> TestSuiteCoverageData -> Value+toCoverallsJson serviceName jobId converter testSuiteCoverageData = object [     "service_job_id" .= jobId,     "service_name" .= serviceName,     "source_files" .= toJsonCoverageList testSuiteCoverageData]-    where toJsonCoverageList = map (uncurry coverageToJson) . M.toList--matchAny :: [String] -> String -> Bool-matchAny patterns fileName = any (`isPrefixOf` fileName) patterns--getMixPath :: String -> String -> FilePath-getMixPath testSuiteName modName = mixDir ++ dirName ++ "/"-    where dirName = case span (/= '/') modName of-              (_, []) -> testSuiteName-              (packageId, _) -> packageId+    where toJsonCoverageList = map (uncurry $ coverageToJson converter) . M.toList  mergeModuleCoverageData :: ModuleCoverageData -> ModuleCoverageData -> ModuleCoverageData mergeModuleCoverageData (source, mix, tixs1) (_, _, tixs2) =@@ -67,12 +81,7 @@ mergeCoverageData = foldr1 (M.unionWith mergeModuleCoverageData)  readMix' :: String -> TixModule -> IO Mix-readMix' name tix = readMix [mixPath] (Right tix)-    where mixPath = getMixPath name modName-          TixModule modName _ _ _ = tix--getTixPath :: String -> IO FilePath-getTixPath testSuiteName = return $ tixDir ++ testSuiteName ++ "/" ++ getTixFileName testSuiteName+readMix' name tix = readMix [getMixPath name tix] (Right tix)  -- | Create a list of coverage data from the tix input readCoverageData :: String                   -- ^ test suite name@@ -92,8 +101,6 @@             return $ M.fromList $ map toFirstAndRest filteredCoverageDataList             where filePath (Mix fp _ _ _ _) = fp                   sourceDirFilter = not . matchAny excludeDirPatterns . fst4-                  fst4 (x, _, _, _) = x-                  toFirstAndRest (a, b, c, d) = (a, (b, c, d))  -- | Generate coveralls json formatted code coverage from hpc coverage data generateCoverallsFromTix :: String   -- ^ CI name@@ -102,6 +109,9 @@                          -> IO Value -- ^ code coverage result in json format generateCoverallsFromTix serviceName jobId config = do     testSuitesCoverages <- mapM (`readCoverageData` excludedDirPatterns) testSuiteNames-    return $ toCoverallsJson serviceName jobId $ mergeCoverageData testSuitesCoverages+    return $ toCoverallsJson serviceName jobId converter $ mergeCoverageData testSuitesCoverages     where excludedDirPatterns = excludedDirs config           testSuiteNames = testSuites config+          converter = case coverageMode config of+              StrictlyFullLines -> strictConverter+              AllowPartialLines -> looseConverter
src/Trace/Hpc/Coveralls/Config.hs view
@@ -1,6 +1,9 @@ module Trace.Hpc.Coveralls.Config where +import Trace.Hpc.Coveralls.Types (CoverageMode)+ data Config = Config {-    testSuites   :: [String],-    excludedDirs :: [FilePath]+    testSuites   :: ![String],+    excludedDirs :: ![FilePath],+    coverageMode :: !CoverageMode     }
src/Trace/Hpc/Coveralls/Curl.hs view
@@ -12,16 +12,12 @@  module Trace.Hpc.Coveralls.Curl ( postJson, PostResult (..) ) where -import Data.Aeson-import Data.Aeson.Types (parseMaybe)+import           Data.Aeson+import           Data.Aeson.Types (parseMaybe) import qualified Data.ByteString.Lazy.Char8 as LBS-import Data.Maybe-import Network.Curl---- | Result to the POST request to coveralls.io-data PostResult =-    PostSuccess URLString -- ^ Coveralls job url-  | PostFailure String    -- ^ error message+import           Data.Maybe+import           Network.Curl+import           Trace.Hpc.Coveralls.Types  parseResponse :: CurlResponse -> PostResult parseResponse r = case respCurlCode r of
+ src/Trace/Hpc/Coveralls/Lix.hs view
@@ -0,0 +1,42 @@+-- |+-- Module:      Trace.Hpc.Coveralls.Lix+-- Copyright:   (c) 2014 Guillaume Nargeot+-- License:     BSD3+-- Maintainer:  Guillaume Nargeot <guillaume+hackage@nargeot.com>+-- Stability:   experimental+-- Portability: portable+--+-- Functions for converting hpc output to line-based code coverage data.++module Trace.Hpc.Coveralls.Lix where++import Data.List+import Data.Ord+import Prelude hiding (getLine)+import Trace.Hpc.Coveralls.Types+import Trace.Hpc.Coveralls.Util+import Trace.Hpc.Mix+import Trace.Hpc.Util++toHit :: [Bool] -> Hit+toHit [] = Irrelevant+toHit [x] = if x then Full else None+toHit xs+    | and xs = Full+    | or xs = Partial+    | otherwise = None++getLine :: MixEntry -> Int+getLine = fffst . fromHpcPos . fst+    where fffst (x, _, _, _) = x++toLineHit :: (MixEntry, Integer) -> (Int, Bool)+toLineHit (entry, cnt) = (getLine entry - 1, cnt > 0)++-- | Convert hpc coverage entries into a line based coverage format+toLix :: Int                   -- ^ Source line count+      -> [(MixEntry, Integer)] -- ^ Mix entries and associated hit count+      -> Lix                   -- ^ Line coverage+toLix lineCount entries = map toHit (groupByIndex lineCount sortedLineHits)+    where sortedLineHits = sortBy (comparing fst) lineHits+          lineHits = map toLineHit entries
+ src/Trace/Hpc/Coveralls/Paths.hs view
@@ -0,0 +1,31 @@+-- |+-- Module:      Trace.Hpc.Coveralls.Paths+-- Copyright:   (c) 2014 Guillaume Nargeot+-- License:     BSD3+-- Maintainer:  Guillaume Nargeot <guillaume+hackage@nargeot.com>+-- Stability:   experimental+--+-- Paths constants and functions for hpc coverage report output.++module Trace.Hpc.Coveralls.Paths where++import Trace.Hpc.Tix++hpcDir :: FilePath+hpcDir = "dist/hpc/"++tixDir :: FilePath+tixDir = hpcDir ++ "tix/"++mixDir :: FilePath+mixDir = hpcDir ++ "mix/"++getMixPath :: String -> TixModule -> FilePath+getMixPath testSuiteName tix = mixDir ++ dirName ++ "/"+    where dirName = case span (/= '/') modName of+              (_, []) -> testSuiteName+              (packageId, _) -> packageId+          TixModule modName _ _ _ = tix++getTixPath :: String -> IO FilePath+getTixPath testSuiteName = return $ tixDir ++ testSuiteName ++ "/" ++ getTixFileName testSuiteName
src/Trace/Hpc/Coveralls/Types.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveDataTypeable #-}+ -- | -- Module:      Trace.Hpc.Coveralls.Types -- Copyright:   (c) 2014 Guillaume Nargeot@@ -5,24 +7,30 @@ -- Maintainer:  Guillaume Nargeot <guillaume+hackage@nargeot.com> -- Stability:   experimental ----- Types to represent code coverage data hpc.+-- Types to represent hpc code coverage data.  module Trace.Hpc.Coveralls.Types where -import Data.Aeson.Types (Value)-import qualified Data.Map as M-import Trace.Hpc.Mix+import Data.Data+import Network.Curl+import System.Console.CmdArgs.Default -type ModuleCoverageData = (-    String,    -- file source code-    Mix,       -- module index data-    [Integer]) -- tixs recorded by hpc+data Hit = Full+         | Partial+         | None+         | Irrelevant+    deriving (Eq, Show) -type TestSuiteCoverageData = M.Map FilePath ModuleCoverageData+type Lix = [Hit] --- single file coverage data in the format defined by coveralls.io-type SimpleCoverage = [CoverageEntry]+instance Default CoverageMode where+    def = AllowPartialLines --- Is there a way to restrict this to only Number and Null?-type CoverageEntry = Value+data CoverageMode = StrictlyFullLines+                  | AllowPartialLines+    deriving (Data, Eq, Show, Typeable) +-- | Result to the POST request to coveralls.io+data PostResult =+    PostSuccess URLString -- ^ Coveralls job url+  | PostFailure String    -- ^ error message
+ src/Trace/Hpc/Coveralls/Util.hs view
@@ -0,0 +1,28 @@+-- |+-- Module:      Trace.Hpc.Coveralls.Util+-- Copyright:   (c) 2014 Guillaume Nargeot+-- License:     BSD3+-- Maintainer:  Guillaume Nargeot <guillaume+hackage@nargeot.com>+-- Stability:   experimental+--+-- Utility functions.++module Trace.Hpc.Coveralls.Util where++import Data.List++fst4 :: (a, b, c, d) -> a+fst4 (x, _, _, _) = x++toFirstAndRest :: (a, b, c, d) -> (a, (b, c, d))+toFirstAndRest (a, b, c, d) = (a, (b, c, d))++matchAny :: [String] -> String -> Bool+matchAny patterns fileName = any (`isPrefixOf` fileName) patterns++groupByIndex :: Int -> [(Int, a)] -> [[a]]+groupByIndex size = take size . flip (++) (repeat []) . groupByIndex' 0 []+    where groupByIndex' _ ys [] = [ys]+          groupByIndex' i ys xx@((xi, x) : xs) = if xi == i+              then groupByIndex' i (x : ys) xs+              else ys : groupByIndex' (i + 1) [] xx
− src/Trace/Hpc/Lix.hs
@@ -1,51 +0,0 @@--- |--- Module:      Trace.Hpc.Lix--- Copyright:   (c) 2014 Guillaume Nargeot--- License:     BSD3--- Maintainer:  Guillaume Nargeot <guillaume+hackage@nargeot.com>--- Stability:   experimental--- Portability: portable------ Types and functions for converting hpc output to line-based code coverage data.--module Trace.Hpc.Lix where--import Data.List-import Data.Ord-import Prelude hiding (getLine)-import Trace.Hpc.Mix-import Trace.Hpc.Util--data Hit = Full | Partial | None | Irrelevant deriving (Eq, Show)--type Lix = [Hit]--groupByIndex :: Int -> [(Int, a)] -> [[a]]-groupByIndex size = take size . flip (++) (repeat []) . groupByIndex' 0 []-    where groupByIndex' _ ys [] = [ys]-          groupByIndex' i ys xx@((xi, x) : xs) = if xi == i-              then groupByIndex' i (x : ys) xs-              else ys : groupByIndex' (i + 1) [] xx--toHit :: [Bool] -> Hit-toHit [] = Irrelevant-toHit [x] = if x then Full else None-toHit xs-    | and xs = Full-    | or xs = Partial-    | otherwise = None--getLine :: MixEntry -> Int-getLine = fffst . fromHpcPos . fst-    where fffst (x, _, _, _) = x--toLineHit :: (MixEntry, Integer) -> (Int, Bool)-toLineHit (entry, cnt) = (getLine entry - 1, cnt > 0)---- | Convert hpc coverage entries into a line based coverage format-toLix :: Int                   -- ^ Source line count-      -> [(MixEntry, Integer)] -- ^ Mix entries and associated hit count-      -> Lix                   -- ^ Line coverage-toLix lineCount entries = map toHit (groupByIndex lineCount sortedLineHits)-    where sortedLineHits = sortBy (comparing fst) lineHits-          lineHits = map toLineHit entries
− src/Trace/Hpc/Paths.hs
@@ -1,19 +0,0 @@--- |--- Module:      Trace.Hpc.Paths--- Copyright:   (c) 2014 Guillaume Nargeot--- License:     BSD3--- Maintainer:  Guillaume Nargeot <guillaume+hackage@nargeot.com>--- Stability:   experimental------ Paths constants for hpc coverage report output.--module Trace.Hpc.Paths where--hpcDir :: FilePath-hpcDir = "dist/hpc/"--tixDir :: FilePath-tixDir = hpcDir ++ "tix/"--mixDir :: FilePath-mixDir = hpcDir ++ "mix/"
test/TestAll.hs view
@@ -2,10 +2,11 @@  import System.Exit ( exitFailure, exitSuccess ) import Test.HUnit-import TestHpcLix+import TestHpcCoverallsLix+import TestHpcCoverallsUtil  allTests :: [Test]-allTests = [testHpcLix]+allTests = [testLix, testUtil]  main :: IO Counts main = do