1 {-# LANGUAGE FlexibleContexts #-}
2 {-# LANGUAGE RankNTypes #-}
4 -----------------------------------------------------------------------------
7 -- Module : Distribution.Simple.Hpc
8 -- Copyright : Thomas Tuegel 2011
11 -- Maintainer : cabal-devel@haskell.org
12 -- Portability : portable
14 -- This module provides functions for locating various HPC-related paths and
15 -- a function for adding the necessary options to a PackageDescription to
16 -- build test suites with HPC enabled.
17 module Distribution
.Simple
.Hpc
28 import Distribution
.Compat
.Prelude
31 import Distribution
.ModuleName
(main
)
32 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
78 -- ^ Directory containing test suite's .mix files
79 mixDir distPref way name
= hpcDir distPrefBuild way
</> "mix" </> name
81 -- This is a hack for HPC over test suites, needed to match the directory
82 -- where HPC saves and reads .mix files when the main library of the same
83 -- package is being processed, perhaps in a previous cabal run (#5213).
84 -- E.g., @distPref@ may be
85 -- @./dist-newstyle/build/x86_64-linux/ghc-9.0.1/cabal-gh5213-0.1/t/tests@
86 -- but the path where library mix files reside has two less components
87 -- at the end (@t/tests@) and this reduced path needs to be passed to
88 -- both @hpc@ and @ghc@. For non-default optimization levels, the path
89 -- suffix is one element longer and the extra path element needs
91 distPrefElements
= splitDirectories distPref
92 distPrefBuild
= case drop (length distPrefElements
- 3) distPrefElements
of
95 take (length distPrefElements
- 3) distPrefElements
99 take (length distPrefElements
- 3) distPrefElements
102 joinPath
$ take (length distPrefElements
- 2) distPrefElements
107 -- ^ \"dist/\" prefix
112 -- ^ Directory containing test suite's .tix files
113 tixDir distPref way name
= hpcDir distPref way
</> "tix" </> name
115 -- | Path to the .tix file containing a test suite's sum statistics.
118 -- ^ \"dist/\" prefix
123 -- ^ Path to test suite's .tix file
124 tixFilePath distPref way name
= tixDir distPref way name
</> name
<.> "tix"
128 -- ^ \"dist/\" prefix
133 -- ^ Path to test suite's HTML markup directory
134 htmlDir distPref way name
= hpcDir distPref way
</> "html" </> name
136 -- | Attempt to guess the way the test suites in this package were compiled
137 -- and linked with the library so the correct module interfaces are found.
138 guessWay
:: LocalBuildInfo
-> Way
140 | withProfExe lbi
= Prof
141 | withDynExe lbi
= Dyn
142 |
otherwise = Vanilla
144 -- | Generate the HTML markup for a test suite.
149 -- ^ \"dist/\" prefix
155 markupTest verbosity lbi distPref libraryName suite library
= do
156 tixFileExists
<- doesFileExist $ tixFilePath distPref way
$ testName
'
157 when tixFileExists
$ do
158 -- behaviour of 'markup' depends on version, so we need *a* version
159 -- but no particular one
161 requireProgramVersion
166 let htmlDir_
= htmlDir distPref way testName
'
171 (tixFilePath distPref way testName
')
174 (exposedModules library
)
176 "Test coverage report written to "
178 </> "hpc_index" <.> "html"
181 testName
' = unUnqualComponentName
$ testName suite
182 mixDirs
= map (mixDir distPref way
) [testName
', libraryName
]
184 -- | Generate the HTML markup for all of a package's test suites.
189 -- ^ \"dist/\" prefix
190 -> PD
.PackageDescription
193 markupPackage verbosity lbi distPref pkg_descr suites
= do
194 let tixFiles
= map (tixFilePath distPref way
) testNames
195 tixFilesExist
<- traverse
doesFileExist tixFiles
196 when (and tixFilesExist
) $ do
197 -- behaviour of 'markup' depends on version, so we need *a* version
198 -- but no particular one
200 requireProgramVersion
205 let outFile
= tixFilePath distPref way libraryName
206 htmlDir
' = htmlDir distPref way libraryName
207 excluded
= concatMap testModules suites
++ [main
]
208 createDirectoryIfMissing
True $ takeDirectory outFile
209 union hpc verbosity tixFiles outFile excluded
210 markup hpc hpcVer verbosity outFile mixDirs htmlDir
' included
212 "Package coverage report written to "
217 testNames
= fmap (unUnqualComponentName
. testName
) suites
218 mixDirs
= map (mixDir distPref way
) $ libraryName
: testNames
219 included
= concatMap (exposedModules
) $ PD
.allLibraries pkg_descr
220 libraryName
= prettyShow
$ PD
.package pkg_descr