1 {-# LANGUAGE FlexibleContexts #-}
2 {-# LANGUAGE NamedFieldPuns #-}
3 {-# LANGUAGE RankNTypes #-}
5 -----------------------------------------------------------------------------
8 -- Module : Distribution.Simple.Hpc
9 -- Copyright : Thomas Tuegel 2011
12 -- Maintainer : cabal-devel@haskell.org
13 -- Portability : portable
15 -- This module provides functions for locating various HPC-related paths and
16 -- a function for adding the necessary options to a PackageDescription to
17 -- build test suites with HPC enabled.
18 module Distribution
.Simple
.Hpc
29 import Distribution
.Compat
.Prelude
32 import Distribution
.ModuleName
(ModuleName
, main
)
33 import Distribution
.PackageDescription
37 import qualified Distribution
.PackageDescription
as PD
38 import Distribution
.Pretty
39 import Distribution
.Simple
.LocalBuildInfo
(LocalBuildInfo
(..))
40 import Distribution
.Simple
.Program
42 , requireProgramVersion
44 import Distribution
.Simple
.Program
.Hpc
(markup
, union)
45 import Distribution
.Simple
.Utils
(notice
)
46 import Distribution
.Types
.UnqualComponentName
47 import Distribution
.Verbosity
(Verbosity
())
48 import Distribution
.Version
(anyVersion
)
49 import System
.Directory
(createDirectoryIfMissing
, doesFileExist)
50 import System
.FilePath
52 -- -------------------------------------------------------------------------
53 -- Haskell Program Coverage
55 data Way
= Vanilla | Prof | Dyn
56 deriving (Bounded
, Enum
, Eq
, Read, Show)
63 -- ^ Directory containing component's HPC .mix files
64 hpcDir distPref way
= distPref
</> "hpc" </> wayDir
76 -- ^ Directory containing test suite's .mix files
77 mixDir distPref way
= hpcDir distPref way
</> "mix"
84 -- ^ Directory containing test suite's .tix files
85 tixDir distPref way
= hpcDir distPref way
</> "tix"
87 -- | Path to the .tix file containing a test suite's sum statistics.
95 -- ^ Path to test suite's .tix file
96 tixFilePath distPref way name
= tixDir distPref way
</> name
<.> "tix"
100 -- ^ \"dist/\" prefix
103 -- ^ Path to test suite's HTML markup directory
104 htmlDir distPref way
= hpcDir distPref way
</> "html"
106 -- | Attempt to guess the way the test suites in this package were compiled
107 -- and linked with the library so the correct module interfaces are found.
108 guessWay
:: LocalBuildInfo
-> Way
110 | withProfExe lbi
= Prof
111 | withDynExe lbi
= Dyn
112 |
otherwise = Vanilla
114 -- | Haskell Program Coverage information required to produce a valid HPC
115 -- report through the `hpc markup` call for the package libraries.
116 data HPCMarkupInfo
= HPCMarkupInfo
117 { pathsToLibsArtifacts
:: [FilePath]
118 -- ^ The paths to the library components whose modules are included in the
120 , libsModulesToInclude
:: [ModuleName
]
121 -- ^ The modules to include in the coverage report
124 -- | Generate the HTML markup for a package's test suites.
130 -- ^ Testsuite \"dist/\" prefix
131 -> PD
.PackageDescription
134 markupPackage verbosity HPCMarkupInfo
{pathsToLibsArtifacts
, libsModulesToInclude
} lbi testDistPref pkg_descr suites
= do
135 let tixFiles
= map (tixFilePath testDistPref way
) testNames
136 tixFilesExist
<- traverse
doesFileExist tixFiles
137 when (and tixFilesExist
) $ do
138 -- behaviour of 'markup' depends on version, so we need *a* version
139 -- but no particular one
141 requireProgramVersion
146 let htmlDir
' = htmlDir testDistPref way
147 -- The tix file used to generate the report is either the testsuite's
148 -- tix file, when there is only one testsuite, or the sum of the tix
149 -- files of all testsuites in the package, which gets put under pkgName
150 -- for this component (a bit weird)
151 -- TODO: cabal-install should pass to Cabal where to put the summed tix
152 -- and report, and perhaps even the testsuites from other packages in
153 -- the project which are currently not accounted for in the summed
155 tixFile
<- case suites
of
156 -- We call 'markupPackage' once for each testsuite to run individually,
157 -- to get the coverage report of just the one testsuite
159 let testName
' = unUnqualComponentName
$ testName oneTest
161 tixFilePath testDistPref way testName
'
162 -- And call 'markupPackage' once per `test` invocation with all the
163 -- testsuites to run, which results in multiple tix files being considered
165 let excluded
= concatMap testModules suites
++ [main
]
166 pkgName
= prettyShow
$ PD
.package pkg_descr
167 summedTixFile
= tixFilePath testDistPref way pkgName
168 createDirectoryIfMissing
True $ takeDirectory summedTixFile
169 union hpc verbosity tixFiles summedTixFile excluded
172 markup hpc hpcVer verbosity tixFile mixDirs htmlDir
' libsModulesToInclude
174 "Package coverage report written to "
179 testNames
= fmap (unUnqualComponentName
. testName
) suites
180 mixDirs
= map (`mixDir` way
) pathsToLibsArtifacts