Skip to content

Commit f91e86b

Browse files
ocharleshololeap
authored andcommitted
Fix test --enable-coverage for multi-package projects
Currently, if you have multiple packages in a project and try and run the test suite of a single package with --enable-coverage, hpc will fail to run. The problem is that _all_ dependencies of the package are built with `-fhpc`, but when we run `hpc markup`, we are only passing the `.mix` directory of the package being tested. Because we built all dependencies with `-fhpc` and we haven't excluded them from the report, we need to supply their `.mix` directories too. The above suggests one fix - compute the transitive closure of all `.mix` directories. However, there is another solution - change from using an exclude-list to using an include-list. This is the approach used in this commit. Explicitly enumerating all modules to _include_ in the report is simpler to code, but is also more likely to be what the user is interested in. Generally, when one generates a coverage report from a test-suite, they want to understand the coverage of the unit being tested. Having coverage information from dependencies is usually not relevant. This is also the behavior from old-style Cabal builds, where there wasn't even a notion of a Cabal project. Fixes haskell#5433.
1 parent 8badf64 commit f91e86b

File tree

5 files changed

+32
-17
lines changed

5 files changed

+32
-17
lines changed

Cabal/src/Distribution/Simple/Hpc.hs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,13 @@ import Distribution.Compat.Prelude
2929

3030
import Distribution.Types.UnqualComponentName
3131
import Distribution.ModuleName ( main )
32+
import qualified Distribution.PackageDescription as PD
3233
import Distribution.PackageDescription
33-
( TestSuite(..)
34+
( Library(..)
35+
, TestSuite(..)
3436
, testModules
3537
)
38+
import Distribution.Pretty
3639
import Distribution.Simple.LocalBuildInfo ( LocalBuildInfo(..) )
3740
import Distribution.Simple.Program
3841
( hpcProgram
@@ -100,8 +103,9 @@ markupTest :: Verbosity
100103
-> FilePath -- ^ \"dist/\" prefix
101104
-> String -- ^ Library name
102105
-> TestSuite
106+
-> Library
103107
-> IO ()
104-
markupTest verbosity lbi distPref libName suite = do
108+
markupTest verbosity lbi distPref libName suite library = do
105109
tixFileExists <- doesFileExist $ tixFilePath distPref way $ testName'
106110
when tixFileExists $ do
107111
-- behaviour of 'markup' depends on version, so we need *a* version
@@ -112,7 +116,7 @@ markupTest verbosity lbi distPref libName suite = do
112116
markup hpc hpcVer verbosity
113117
(tixFilePath distPref way testName') mixDirs
114118
htmlDir_
115-
(testModules suite ++ [ main ])
119+
(exposedModules library)
116120
notice verbosity $ "Test coverage report written to "
117121
++ htmlDir_ </> "hpc_index" <.> "html"
118122
where
@@ -124,10 +128,10 @@ markupTest verbosity lbi distPref libName suite = do
124128
markupPackage :: Verbosity
125129
-> LocalBuildInfo
126130
-> FilePath -- ^ \"dist/\" prefix
127-
-> String -- ^ Library name
131+
-> PD.PackageDescription
128132
-> [TestSuite]
129133
-> IO ()
130-
markupPackage verbosity lbi distPref libName suites = do
134+
markupPackage verbosity lbi distPref pkg_descr suites = do
131135
let tixFiles = map (tixFilePath distPref way) testNames
132136
tixFilesExist <- traverse doesFileExist tixFiles
133137
when (and tixFilesExist) $ do
@@ -140,10 +144,12 @@ markupPackage verbosity lbi distPref libName suites = do
140144
excluded = concatMap testModules suites ++ [ main ]
141145
createDirectoryIfMissing True $ takeDirectory outFile
142146
union hpc verbosity tixFiles outFile excluded
143-
markup hpc hpcVer verbosity outFile mixDirs htmlDir' excluded
147+
markup hpc hpcVer verbosity outFile mixDirs htmlDir' included
144148
notice verbosity $ "Package coverage report written to "
145149
++ htmlDir' </> "hpc_index.html"
146150
where
147151
way = guessWay lbi
148152
testNames = fmap (unUnqualComponentName . testName) suites
149153
mixDirs = map (mixDir distPref way) $ libName : testNames
154+
included = concatMap (exposedModules) $ PD.allLibraries pkg_descr
155+
libName = prettyShow $ PD.package pkg_descr

Cabal/src/Distribution/Simple/Program/Hpc.hs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ markup :: ConfiguredProgram
4242
-> FilePath -- ^ Path to .tix file
4343
-> [FilePath] -- ^ Paths to .mix file directories
4444
-> FilePath -- ^ Path where html output should be located
45-
-> [ModuleName] -- ^ List of modules to exclude from report
45+
-> [ModuleName] -- ^ List of modules to include in the report
4646
-> IO ()
47-
markup hpc hpcVer verbosity tixFile hpcDirs destDir excluded = do
47+
markup hpc hpcVer verbosity tixFile hpcDirs destDir included = do
4848
hpcDirs' <- if withinRange hpcVer (orLaterVersion version07)
4949
then return hpcDirs
5050
else do
@@ -63,7 +63,7 @@ markup hpc hpcVer verbosity tixFile hpcDirs destDir excluded = do
6363
hpcDirs'' <- traverse makeRelativeToCurrentDirectory hpcDirs'
6464

6565
runProgramInvocation verbosity
66-
(markupInvocation hpc tixFile hpcDirs'' destDir excluded)
66+
(markupInvocation hpc tixFile hpcDirs'' destDir included)
6767
where
6868
version07 = mkVersion [0, 7]
6969
(passedDirs, droppedDirs) = splitAt 1 hpcDirs
@@ -73,16 +73,15 @@ markupInvocation :: ConfiguredProgram
7373
-> [FilePath] -- ^ Paths to .mix file directories
7474
-> FilePath -- ^ Path where html output should be
7575
-- located
76-
-> [ModuleName] -- ^ List of modules to exclude from
77-
-- report
76+
-> [ModuleName] -- ^ List of modules to include
7877
-> ProgramInvocation
79-
markupInvocation hpc tixFile hpcDirs destDir excluded =
78+
markupInvocation hpc tixFile hpcDirs destDir included =
8079
let args = [ "markup", tixFile
8180
, "--destdir=" ++ destDir
8281
]
8382
++ map ("--hpcdir=" ++) hpcDirs
84-
++ ["--exclude=" ++ prettyShow moduleName
85-
| moduleName <- excluded ]
83+
++ ["--include=" ++ prettyShow moduleName
84+
| moduleName <- included ]
8685
in programInvocation hpc args
8786

8887
union :: ConfiguredProgram

Cabal/src/Distribution/Simple/Test.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ test args pkg_descr lbi flags = do
119119
writeFile packageLogFile $ show packageLog
120120

121121
when (LBI.testCoverage lbi) $
122-
markupPackage verbosity lbi distPref (prettyShow $ PD.package pkg_descr) $
122+
markupPackage verbosity lbi distPref pkg_descr $
123123
map (fst . fst) testsToRun
124124

125125
unless allOk exitFailure

Cabal/src/Distribution/Simple/Test/ExeV10.hs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,12 @@ runTest pkg_descr lbi clbi flags suite = do
142142
notice verbosity $ summarizeSuiteFinish suiteLog
143143

144144
when isCoverageEnabled $
145-
markupTest verbosity lbi distPref (prettyShow $ PD.package pkg_descr) suite
145+
case PD.library pkg_descr of
146+
Nothing ->
147+
die' verbosity $ "Error: test coverage is only supported for packages with a library component"
148+
149+
Just library ->
150+
markupTest verbosity lbi distPref (prettyShow $ PD.package pkg_descr) suite library
146151

147152
return suiteLog
148153
where

Cabal/src/Distribution/Simple/Test/LibV09.hs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,12 @@ runTest pkg_descr lbi clbi flags suite = do
158158
notice verbosity $ summarizeSuiteFinish suiteLog
159159

160160
when isCoverageEnabled $
161-
markupTest verbosity lbi distPref (prettyShow $ PD.package pkg_descr) suite
161+
case PD.library pkg_descr of
162+
Nothing ->
163+
die' verbosity $ "Error: test coverage is only supported for packages with a library component"
164+
165+
Just library ->
166+
markupTest verbosity lbi distPref (prettyShow $ PD.package pkg_descr) suite library
162167

163168
return suiteLog
164169
where

0 commit comments

Comments
 (0)