validate dependabot configuration
[cabal.git] / Cabal-tests / tests / custom-setup / CabalDoctestSetup.hs
bloba89ce9b36e7a7b138ac337e836161f96b64bf68e
1 -- This is Distribution.Extra.Doctest module from cabal-doctest-1.0.4
2 -- This isn't technically a Custom-Setup script, but it /was/.
4 {-# LANGUAGE FlexibleInstances #-}
6 {-
8 Copyright (c) 2017, Oleg Grenrus
10 All rights reserved.
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
15 * Redistributions of source code must retain the above copyright
16 notice, this list of conditions and the following disclaimer.
18 * Redistributions in binary form must reproduce the above
19 copyright notice, this list of conditions and the following
20 disclaimer in the documentation and/or other materials provided
21 with the distribution.
23 * Neither the name of Oleg Grenrus nor the names of other
24 contributors may be used to endorse or promote products derived
25 from this software without specific prior written permission.
27 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 {-# LANGUAGE CPP #-}
42 {-# LANGUAGE OverloadedStrings #-}
43 -- | The provided 'generateBuildModule' generates 'Build_doctests' module.
44 -- That module exports enough configuration, so your doctests could be simply
46 -- @
47 -- module Main where
49 -- import Build_doctests (flags, pkgs, module_sources)
50 -- import Data.Foldable (traverse_)
51 -- import Test.Doctest (doctest)
53 -- main :: IO ()
54 -- main = do
55 -- traverse_ putStrLn args -- optionally print arguments
56 -- doctest args
57 -- where
58 -- args = flags ++ pkgs ++ module_sources
59 -- @
61 -- To use this library in the @Setup.hs@, you should specify a @custom-setup@
62 -- section in the cabal file, for example:
64 -- @
65 -- custom-setup
66 -- setup-depends:
67 -- base >= 4 && <5,
68 -- cabal-doctest >= 1 && <1.1
69 -- @
71 -- /Note:/ you don't need to depend on @Cabal@ if you use only
72 -- 'defaultMainWithDoctests' in the @Setup.hs@.
74 module CabalDoctestSetup (
75 defaultMainWithDoctests,
76 defaultMainAutoconfWithDoctests,
77 addDoctestsUserHook,
78 doctestsUserHooks,
79 generateBuildModule,
80 ) where
82 -- Hacky way to suppress few deprecation warnings.
83 #if MIN_VERSION_Cabal(1,24,0)
84 #define InstalledPackageId UnitId
85 #endif
87 import Control.Monad
88 (when)
89 import Data.IORef
90 (modifyIORef, newIORef, readIORef)
91 import Data.List
92 (nub)
93 import Data.Maybe
94 (mapMaybe, maybeToList)
95 import Data.String
96 (fromString)
97 import Distribution.Package
98 (InstalledPackageId, Package (..))
99 import Distribution.PackageDescription
100 (BuildInfo (..), Executable (..), GenericPackageDescription,
101 Library (..), PackageDescription, TestSuite (..))
102 import Distribution.Simple
103 (UserHooks (..), autoconfUserHooks, defaultMainWithHooks,
104 simpleUserHooks)
105 import Distribution.Simple.Compiler
106 (CompilerFlavor (GHC), CompilerId (..), PackageDB (..), compilerId)
107 import Distribution.Simple.LocalBuildInfo
108 (ComponentLocalBuildInfo (componentPackageDeps), LocalBuildInfo,
109 compiler, withExeLBI, withLibLBI, withPackageDB, withTestLBI
111 import Distribution.Simple.Setup
112 ( CommonSetupFlags(..)
113 , BuildFlags(..)
114 , HaddockFlags (..)
115 , emptyBuildFlags,
116 fromFlag)
117 import Distribution.Simple.Utils
118 (createDirectoryIfMissingVerbose, info)
119 import Distribution.Text
120 (display)
121 import Distribution.Verbosity
122 import System.FilePath
123 ((</>))
125 import qualified Data.Foldable as F
126 (for_)
127 import qualified Data.Traversable as T
128 (traverse)
130 #if MIN_VERSION_Cabal(1,25,0)
131 import Distribution.Simple.BuildPaths
132 (autogenComponentModulesDir)
133 #else
134 import Distribution.Simple.BuildPaths
135 (autogenModulesDir)
136 #endif
138 #if MIN_VERSION_Cabal(2,0,0)
139 import Distribution.Types.MungedPackageId
140 (MungedPackageId)
141 import Distribution.Types.UnqualComponentName
142 (unUnqualComponentName)
144 -- For amendGPD
145 import Distribution.PackageDescription
146 (CondTree (..))
147 import Distribution.Types.GenericPackageDescription
148 (GenericPackageDescription (condTestSuites))
150 import Distribution.Version
151 (mkVersion)
152 #else
153 import Data.Version
154 (Version (..))
155 import Distribution.Package
156 (PackageId)
157 #endif
159 #if MIN_VERSION_Cabal(3,11,0)
160 import Distribution.Utils.Path
161 ( SymbolicPathX
162 , makeSymbolicPath
163 , makeRelativePathEx )
164 import qualified Distribution.Utils.Path as Cabal
165 (getSymbolicPath)
166 import Distribution.Simple.Utils
167 (findFileEx)
168 #elif MIN_VERSION_Cabal(3,0,0)
169 import Distribution.Utils.Path
170 (SymbolicPath)
171 import qualified Distribution.Utils.Path as Cabal
172 (getSymbolicPath)
173 import Distribution.Simple.Utils
174 (findFileEx)
175 #else
176 import Distribution.Simple.Utils
177 (findFile)
178 #endif
180 #if MIN_VERSION_Cabal(3,0,0)
181 import Distribution.Types.LibraryName
182 (libraryNameString)
183 #endif
185 #if MIN_VERSION_directory(1,2,2)
186 import System.Directory
187 (makeAbsolute)
188 #else
189 import System.Directory
190 (getCurrentDirectory)
191 import System.FilePath
192 (isAbsolute)
194 makeAbsolute :: FilePath -> IO FilePath
195 makeAbsolute p | isAbsolute p = return p
196 | otherwise = do
197 cwd <- getCurrentDirectory
198 return $ cwd </> p
199 #endif
201 findFile' :: Verbosity -> [FilePath] -> FilePath -> IO FilePath
202 #if MIN_VERSION_Cabal(3,11,0)
203 findFile' verbosity searchPath fileName
204 = toFilePath <$>
205 findFileEx verbosity
206 (fmap makeSymbolicPath searchPath) (makeRelativePathEx fileName)
207 #elif MIN_VERSION_Cabal(3,0,0)
208 findFile' verbosity searchPath fileName
209 = findFileEx verbosity searchPath fileName
210 #else
211 findFile' _verbosity searchPath fileName
212 = findFile searchPath fileName
213 #endif
215 #if !MIN_VERSION_Cabal(2,0,0)
216 mkVersion :: [Int] -> Version
217 mkVersion ds = Version ds []
218 #endif
220 class CompatPath p where
221 toFilePath :: p -> FilePath
222 instance CompatPath FilePath where
223 toFilePath = id
224 #if MIN_VERSION_Cabal(3,11,0)
225 instance CompatPath (SymbolicPathX allowAbs from to) where
226 toFilePath = Cabal.getSymbolicPath
227 #elif MIN_VERSION_Cabal(3,5,0)
228 instance CompatPath (SymbolicPath from to) where
229 toFilePath = Cabal.getSymbolicPath
230 #endif
232 -------------------------------------------------------------------------------
233 -- Mains
234 -------------------------------------------------------------------------------
236 -- | A default main with doctests:
238 -- @
239 -- import Distribution.Extra.Doctest
240 -- (defaultMainWithDoctests)
242 -- main :: IO ()
243 -- main = defaultMainWithDoctests "doctests"
244 -- @
245 defaultMainWithDoctests
246 :: String -- ^ doctests test-suite name
247 -> IO ()
248 defaultMainWithDoctests = defaultMainWithHooks . doctestsUserHooks
250 -- | Like 'defaultMainWithDoctests', for 'build-type: Configure' packages.
252 -- @since 1.0.2
253 defaultMainAutoconfWithDoctests
254 :: String -- ^ doctests test-suite name
255 -> IO ()
256 defaultMainAutoconfWithDoctests n =
257 defaultMainWithHooks (addDoctestsUserHook n autoconfUserHooks)
259 -- | 'simpleUserHooks' with 'generateBuildModule' prepended to the 'buildHook'.
260 doctestsUserHooks
261 :: String -- ^ doctests test-suite name
262 -> UserHooks
263 doctestsUserHooks testsuiteName =
264 addDoctestsUserHook testsuiteName simpleUserHooks
266 -- |
268 -- @since 1.0.2
269 addDoctestsUserHook :: String -> UserHooks -> UserHooks
270 addDoctestsUserHook testsuiteName uh = uh
271 { buildHook = \pkg lbi hooks flags -> do
272 generateBuildModule testsuiteName flags pkg lbi
273 buildHook uh pkg lbi hooks flags
274 -- We use confHook to add "Build_Doctests" to otherModules and autogenModules.
276 -- We cannot use HookedBuildInfo as it let's alter only the library and executables.
277 , confHook = \(gpd, hbi) flags ->
278 confHook uh (amendGPD testsuiteName gpd, hbi) flags
279 , haddockHook = \pkg lbi hooks flags -> do
280 generateBuildModule testsuiteName (haddockToBuildFlags flags) pkg lbi
281 haddockHook uh pkg lbi hooks flags
284 -- | Convert only flags used by 'generateBuildModule'.
285 haddockToBuildFlags :: HaddockFlags -> BuildFlags
286 haddockToBuildFlags f =
287 #if MIN_VERSION_Cabal(3,11,0)
288 emptyBuildFlags
289 { buildCommonFlags = haddockCommonFlags f }
290 #else
291 emptyBuildFlags
292 { buildVerbosity = haddockVerbosity f
293 , buildDistPref = haddockDistPref f
295 #endif
297 data Name = NameLib (Maybe String) | NameExe String deriving (Eq, Show)
299 nameToString :: Name -> String
300 nameToString n = case n of
301 NameLib x -> maybe "" (("_lib_" ++) . map fixchar) x
302 NameExe x -> "_exe_" ++ map fixchar x
303 where
304 -- Taken from Cabal:
305 -- https://github.com/haskell/cabal/blob/20de0bfea72145ba1c37e3f500cee5258cc18e51/Cabal/Distribution/Simple/Build/Macros.hs#L156-L158
307 -- Needed to fix component names with hyphens in them, as hyphens aren't
308 -- allowed in Haskell identifier names.
309 fixchar :: Char -> Char
310 fixchar '-' = '_'
311 fixchar c = c
313 data Component = Component Name [String] [String] [String]
314 deriving Show
316 -- | Generate a build module for the test suite.
318 -- @
319 -- import Distribution.Simple
320 -- (defaultMainWithHooks, UserHooks(..), simpleUserHooks)
321 -- import Distribution.Extra.Doctest
322 -- (generateBuildModule)
324 -- main :: IO ()
325 -- main = defaultMainWithHooks simpleUserHooks
326 -- { buildHook = \pkg lbi hooks flags -> do
327 -- generateBuildModule "doctests" flags pkg lbi
328 -- buildHook simpleUserHooks pkg lbi hooks flags
329 -- }
330 -- @
331 generateBuildModule
332 :: String -- ^ doctests test-suite name
333 -> BuildFlags -> PackageDescription -> LocalBuildInfo -> IO ()
334 generateBuildModule testSuiteName flags pkg lbi = do
335 let verbosity = fromFlag (buildVerbosity flags)
336 let distPref = fromFlag (buildDistPref flags)
338 -- Package DBs & environments
339 let dbStack = withPackageDB lbi ++ [ SpecificPackageDB $ toFilePath distPref </> "package.conf.inplace" ]
340 let dbFlags = "-hide-all-packages" : packageDbArgs dbStack
341 let envFlags
342 | ghcCanBeToldToIgnorePkgEnvs = [ "-package-env=-" ]
343 | otherwise = []
345 withTestLBI pkg lbi $ \suite suitecfg -> when (testName suite == fromString testSuiteName) $ do
346 let testAutogenDir = toFilePath $
347 #if MIN_VERSION_Cabal(1,25,0)
348 autogenComponentModulesDir lbi suitecfg
349 #else
350 autogenModulesDir lbi
351 #endif
353 createDirectoryIfMissingVerbose verbosity True testAutogenDir
355 let buildDoctestsFile = testAutogenDir </> "Build_doctests.hs"
357 -- First, we create the autogen'd module Build_doctests.
358 -- Initially populate Build_doctests with a simple preamble.
359 info verbosity $ "cabal-doctest: writing Build_doctests to " ++ buildDoctestsFile
360 writeFile buildDoctestsFile $ unlines
361 [ "module Build_doctests where"
362 , ""
363 , "import Prelude"
364 , ""
365 , "data Name = NameLib (Maybe String) | NameExe String deriving (Eq, Show)"
366 , "data Component = Component Name [String] [String] [String] deriving (Eq, Show)"
367 , ""
370 -- we cannot traverse, only traverse_
371 -- so we use IORef to collect components
372 componentsRef <- newIORef []
374 let testBI = testBuildInfo suite
376 -- TODO: `words` is not proper parser (no support for quotes)
377 let additionalFlags = maybe [] words
378 $ lookup "x-doctest-options"
379 $ customFieldsBI testBI
381 let additionalModules = maybe [] words
382 $ lookup "x-doctest-modules"
383 $ customFieldsBI testBI
385 let additionalDirs' = maybe [] words
386 $ lookup "x-doctest-source-dirs"
387 $ customFieldsBI testBI
389 additionalDirs <- mapM (fmap ("-i" ++) . makeAbsolute) additionalDirs'
391 -- Next, for each component (library or executable), we get to Build_doctests
392 -- the sets of flags needed to run doctest on that component.
393 let getBuildDoctests withCompLBI mbCompName compExposedModules compMainIs compBuildInfo =
394 withCompLBI pkg lbi $ \comp compCfg -> do
395 let compBI = compBuildInfo comp
397 -- modules
398 let modules = compExposedModules comp ++ otherModules compBI
399 -- it seems that doctest is happy to take in module names, not actual files!
400 let module_sources = modules
402 -- We need the directory with the component's cabal_macros.h!
404 let compAutogenDir =
405 toFilePath $
406 #if MIN_VERSION_Cabal(1,25,0)
407 autogenComponentModulesDir lbi compCfg
408 #else
409 autogenModulesDir lbi
410 #endif
412 -- Lib sources and includes
413 iArgsNoPrefix
414 <- mapM makeAbsolute
415 $ compAutogenDir -- autogenerated files
416 : (toFilePath distPref ++ "/build") -- preprocessed files (.hsc -> .hs); "build" is hardcoded in Cabal.
417 : map toFilePath (hsSourceDirs compBI)
418 includeArgs <- mapM (fmap ("-I"++) . makeAbsolute . toFilePath) $ includeDirs compBI
419 -- We clear all includes, so the CWD isn't used.
420 let iArgs' = map ("-i"++) iArgsNoPrefix
421 iArgs = "-i" : iArgs'
423 -- default-extensions
424 let extensionArgs = map (("-X"++) . display) $ defaultExtensions compBI
426 -- CPP includes, i.e. include cabal_macros.h
427 let cppFlags = map ("-optP"++) $
428 [ "-include", compAutogenDir ++ "/cabal_macros.h" ]
429 ++ cppOptions compBI
431 -- Unlike other modules, the main-is module of an executable is not
432 -- guaranteed to share a module name with its filepath name. That is,
433 -- even though the main-is module is named Main, its filepath might
434 -- actually be Something.hs. To account for this possibility, we simply
435 -- pass the full path to the main-is module instead.
436 mainIsPath <- T.traverse (findFile' verbosity iArgsNoPrefix) (compMainIs comp)
438 let all_sources = map display module_sources
439 ++ additionalModules
440 ++ maybeToList mainIsPath
442 let component = Component
443 (mbCompName comp)
444 (formatDeps $ testDeps compCfg suitecfg)
445 (concat
446 [ iArgs
447 , additionalDirs
448 , includeArgs
449 , envFlags
450 , dbFlags
451 , cppFlags
452 , extensionArgs
453 , additionalFlags
455 all_sources
457 -- modify IORef, append component
458 modifyIORef componentsRef (\cs -> cs ++ [component])
460 -- For now, we only check for doctests in libraries and executables.
461 getBuildDoctests withLibLBI mbLibraryName exposedModules (const Nothing) libBuildInfo
462 getBuildDoctests withExeLBI (NameExe . executableName) (const []) (Just . toFilePath . modulePath) buildInfo
464 components <- readIORef componentsRef
465 F.for_ components $ \(Component cmpName cmpPkgs cmpFlags cmpSources) -> do
466 let compSuffix = nameToString cmpName
467 pkgs_comp = "pkgs" ++ compSuffix
468 flags_comp = "flags" ++ compSuffix
469 module_sources_comp = "module_sources" ++ compSuffix
471 -- write autogen'd file
472 appendFile buildDoctestsFile $ unlines
473 [ -- -package-id etc. flags
474 pkgs_comp ++ " :: [String]"
475 , pkgs_comp ++ " = " ++ show cmpPkgs
476 , ""
477 , flags_comp ++ " :: [String]"
478 , flags_comp ++ " = " ++ show cmpFlags
479 , ""
480 , module_sources_comp ++ " :: [String]"
481 , module_sources_comp ++ " = " ++ show cmpSources
482 , ""
485 -- write enabled components, i.e. x-doctest-components
486 -- if none enabled, pick library
487 let enabledComponents = maybe [NameLib Nothing] (mapMaybe parseComponentName . words)
488 $ lookup "x-doctest-components"
489 $ customFieldsBI testBI
491 let components' =
492 filter (\(Component n _ _ _) -> n `elem` enabledComponents) components
493 appendFile buildDoctestsFile $ unlines
494 [ "-- " ++ show enabledComponents
495 , "components :: [Component]"
496 , "components = " ++ show components'
499 where
500 parseComponentName :: String -> Maybe Name
501 parseComponentName "lib" = Just (NameLib Nothing)
502 parseComponentName ('l' : 'i' : 'b' : ':' : x) = Just (NameLib (Just x))
503 parseComponentName ('e' : 'x' : 'e' : ':' : x) = Just (NameExe x)
504 parseComponentName _ = Nothing
506 -- we do this check in Setup, as then doctests don't need to depend on Cabal
507 isNewCompiler = case compilerId $ compiler lbi of
508 CompilerId GHC v -> v >= mkVersion [7,6]
509 _ -> False
511 ghcCanBeToldToIgnorePkgEnvs :: Bool
512 ghcCanBeToldToIgnorePkgEnvs = case compilerId $ compiler lbi of
513 CompilerId GHC v -> v >= mkVersion [8,4,4]
514 _ -> False
516 formatDeps = map formatOne
517 formatOne (installedPkgId, pkgId)
518 -- The problem is how different cabal executables handle package databases
519 -- when doctests depend on the library
521 -- If the pkgId is current package, we don't output the full package-id
522 -- but only the name
524 -- Because of MungedPackageId we compare display version of identifiers
525 -- not the identifiers themfselves.
526 | display (packageId pkg) == display pkgId = "-package=" ++ display pkgId
527 | otherwise = "-package-id=" ++ display installedPkgId
529 -- From Distribution.Simple.Program.GHC
530 packageDbArgs :: [PackageDB] -> [String]
531 packageDbArgs | isNewCompiler = packageDbArgsDb
532 | otherwise = packageDbArgsConf
534 -- GHC <7.6 uses '-package-conf' instead of '-package-db'.
535 packageDbArgsConf :: [PackageDB] -> [String]
536 packageDbArgsConf dbstack = case dbstack of
537 (GlobalPackageDB:UserPackageDB:dbs) -> concatMap specific dbs
538 (GlobalPackageDB:dbs) -> ("-no-user-package-conf")
539 : concatMap specific dbs
540 _ -> ierror
541 where
542 specific (SpecificPackageDB db) = [ "-package-conf=" ++ db ]
543 specific _ = ierror
544 ierror = error $ "internal error: unexpected package db stack: "
545 ++ show dbstack
547 -- GHC >= 7.6 uses the '-package-db' flag. See
548 -- https://ghc.haskell.org/trac/ghc/ticket/5977.
549 packageDbArgsDb :: [PackageDB] -> [String]
550 -- special cases to make arguments prettier in common scenarios
551 packageDbArgsDb dbstack = case dbstack of
552 (GlobalPackageDB:UserPackageDB:dbs)
553 | all isSpecific dbs -> concatMap single dbs
554 (GlobalPackageDB:dbs)
555 | all isSpecific dbs -> "-no-user-package-db"
556 : concatMap single dbs
557 dbs -> "-clear-package-db"
558 : concatMap single dbs
559 where
560 single (SpecificPackageDB db) = [ "-package-db=" ++ db ]
561 single GlobalPackageDB = [ "-global-package-db" ]
562 single UserPackageDB = [ "-user-package-db" ]
563 isSpecific (SpecificPackageDB _) = True
564 isSpecific _ = False
566 mbLibraryName :: Library -> Name
567 #if MIN_VERSION_Cabal(3,0,0)
568 mbLibraryName = NameLib . fmap unUnqualComponentName . libraryNameString . libName
569 #elif MIN_VERSION_Cabal(2,0,0)
570 -- Cabal-2.0 introduced internal libraries, which are named.
571 mbLibraryName = NameLib . fmap unUnqualComponentName . libName
572 #else
573 -- Before that, there was only ever at most one library per
574 -- .cabal file, which has no name.
575 mbLibraryName _ = NameLib Nothing
576 #endif
578 executableName :: Executable -> String
579 #if MIN_VERSION_Cabal(2,0,0)
580 executableName = unUnqualComponentName . exeName
581 #else
582 executableName = exeName
583 #endif
585 -- | In compat settings it's better to omit the type-signature
586 testDeps :: ComponentLocalBuildInfo -> ComponentLocalBuildInfo
587 #if MIN_VERSION_Cabal(2,0,0)
588 -> [(InstalledPackageId, MungedPackageId)]
589 #else
590 -> [(InstalledPackageId, PackageId)]
591 #endif
592 testDeps xs ys = nub $ componentPackageDeps xs ++ componentPackageDeps ys
594 amendGPD
595 :: String -- ^ doctests test-suite name
596 -> GenericPackageDescription
597 -> GenericPackageDescription
598 #if !(MIN_VERSION_Cabal(2,0,0))
599 amendGPD _ gpd = gpd
600 #else
601 amendGPD testSuiteName gpd = gpd
602 { condTestSuites = map f (condTestSuites gpd)
604 where
605 f (name, condTree)
606 | name == fromString testSuiteName = (name, condTree')
607 | otherwise = (name, condTree)
608 where
609 -- I miss 'lens'
610 testSuite = condTreeData condTree
611 bi = testBuildInfo testSuite
612 om = otherModules bi
613 am = autogenModules bi
615 -- Cons the module to both other-modules and autogen-modules.
616 -- At the moment, cabal-spec-2.0 and cabal-spec-2.2 don't have
617 -- "all autogen-modules are other-modules if they aren't exposed-modules"
618 -- rule. Hopefully cabal-spec-3.0 will have.
620 -- Note: we `nub`, because it's unclear if that's ok to have duplicate
621 -- modules in the lists.
622 om' = nub $ mn : om
623 am' = nub $ mn : am
625 mn = fromString "Build_doctests"
627 bi' = bi { otherModules = om', autogenModules = am' }
628 testSuite' = testSuite { testBuildInfo = bi' }
629 condTree' = condTree { condTreeData = testSuite' }
630 #endif