1 {-# LANGUAGE BangPatterns #-}
2 {-# LANGUAGE DeriveDataTypeable #-}
3 {-# LANGUAGE OverloadedStrings #-}
4 {-# LANGUAGE RankNTypes #-}
5 {-# LANGUAGE ScopedTypeVariables #-}
6 -- For the handy instance IsString PackageIdentifier
7 {-# OPTIONS_GHC -fno-warn-orphans #-}
11 import Distribution
.Client
.Compat
.Prelude
14 import Distribution
.Client
.DistDirLayout
15 import Distribution
.Client
.HttpUtils
16 import qualified Distribution
.Client
.InstallPlan
as InstallPlan
17 import Distribution
.Client
.ProjectBuilding
18 import Distribution
.Client
.ProjectConfig
19 import Distribution
.Client
.ProjectOrchestration
20 ( distinctTargetComponents
23 import Distribution
.Client
.ProjectPlanning
24 import Distribution
.Client
.ProjectPlanning
.Types
25 import Distribution
.Client
.TargetProblem
29 import Distribution
.Client
.TargetSelector
hiding (DirActions
(..))
30 import qualified Distribution
.Client
.TargetSelector
as TS
(DirActions
(..))
31 import Distribution
.Client
.Targets
33 , UserConstraintScope
(UserAnyQualifier
)
35 import Distribution
.Client
.Types
36 ( PackageLocation
(..)
37 , PackageSpecifier
(..)
38 , UnresolvedSourcePackage
40 import Distribution
.Solver
.Types
.ConstraintSource
41 ( ConstraintSource
(ConstraintSourceUnknown
)
43 import Distribution
.Solver
.Types
.PackageConstraint
44 ( PackageProperty
(PackagePropertySource
)
46 import Distribution
.Solver
.Types
.SourcePackage
as SP
48 import qualified Distribution
.Client
.CmdBench
as CmdBench
49 import qualified Distribution
.Client
.CmdBuild
as CmdBuild
50 import qualified Distribution
.Client
.CmdHaddock
as CmdHaddock
51 import qualified Distribution
.Client
.CmdListBin
as CmdListBin
52 import qualified Distribution
.Client
.CmdRepl
as CmdRepl
53 import qualified Distribution
.Client
.CmdRun
as CmdRun
54 import qualified Distribution
.Client
.CmdTest
as CmdTest
56 import qualified Distribution
.Client
.CmdHaddockProject
as CmdHaddockProject
57 import Distribution
.Client
.Config
(SavedConfig
(savedGlobalFlags
), createDefaultConfigFile
, loadConfig
)
58 import Distribution
.Client
.GlobalFlags
(defaultGlobalFlags
)
59 import Distribution
.Client
.Setup
(globalCommand
, globalStoreDir
)
60 import Distribution
.InstalledPackageInfo
(InstalledPackageInfo
)
61 import Distribution
.ModuleName
(ModuleName
)
62 import Distribution
.Package
63 import Distribution
.PackageDescription
64 import Distribution
.Simple
.Command
65 import Distribution
.Simple
.Compiler
66 import qualified Distribution
.Simple
.Flag
as Flag
67 import Distribution
.Simple
.Setup
(CommonSetupFlags
(..), HaddockFlags
(..), HaddockProjectFlags
(..), defaultCommonSetupFlags
, defaultHaddockFlags
, defaultHaddockProjectFlags
, toFlag
)
68 import Distribution
.System
69 import Distribution
.Text
70 import Distribution
.Utils
.Path
(unsafeMakeSymbolicPath
)
71 import Distribution
.Version
72 import IntegrationTests2
.CPP
74 import Data
.List
(isInfixOf
)
75 import qualified Data
.Map
as Map
76 import qualified Data
.Set
as Set
78 import Control
.Concurrent
(threadDelay
)
79 import Control
.Exception
hiding (assert
)
81 import System
.Directory
82 import System
.Environment
(setEnv
)
83 import System
.FilePath
84 import System
.IO (hPutStrLn, stderr)
85 import System
.Process
(callProcess
)
87 import Data
.Tagged
(Tagged
(..))
89 import Test
.Tasty
.HUnit
90 import Test
.Tasty
.Options
92 import qualified Data
.ByteString
as BS
93 import Data
.Maybe (fromJust)
94 import Distribution
.Client
.GlobalFlags
(GlobalFlags
, globalNix
)
95 import Distribution
.Simple
.Flag
(Flag
(Flag
, NoFlag
))
96 import Distribution
.Types
.ParStrat
100 -- this is needed to ensure tests aren't affected by the user's cabal config
101 cwd
<- getCurrentDirectory
102 let configDir
= cwd
</> basedir
</> "config" </> "cabal-config"
103 setEnv
"CABAL_DIR" configDir
104 removeDirectoryRecursive configDir
<|
> return ()
105 createDirectoryIfMissing
True configDir
107 -- NOTE: This is running the `cabal` from the user environment, which is
108 -- generally not the `cabal` being tested!
109 callProcess
"cabal" ["-v0", "user-config", "init", "-f"]
110 callProcess
"cabal" ["update"]
111 defaultMainWithIngredients
112 (defaultIngredients
++ [includingOptions projectConfigOptionDescriptions
])
113 ( withProjectConfig
$ \config
->
115 "Integration tests (internal)"
119 tests
:: ProjectConfig
-> [TestTree
]
123 -- \* dry-run tests with changes
124 [ testGroup
"Discovery and planning" $
125 [ testCase
"no package" (testExceptionInFindingPackage config
)
126 , testCase
"no package2" (testExceptionInFindingPackage2 config
)
127 , testCase
"proj conf1" (testExceptionInProjectConfig config
)
129 , testGroup
"Target selectors" $
130 [ testCaseSteps
"valid" testTargetSelectors
131 , testCase
"bad syntax" testTargetSelectorBadSyntax
132 , testCaseSteps
"ambiguous syntax" testTargetSelectorAmbiguous
133 , testCase
"no current pkg" testTargetSelectorNoCurrentPackage
134 , testCase
"no targets" testTargetSelectorNoTargets
135 , testCase
"project empty" testTargetSelectorProjectEmpty
136 , testCase
"canonicalized path" testTargetSelectorCanonicalizedPath
137 , testCase
"problems (common)" (testTargetProblemsCommon config
)
138 , testCaseSteps
"problems (build)" (testTargetProblemsBuild config
)
139 , testCaseSteps
"problems (repl)" (testTargetProblemsRepl config
)
140 , testCaseSteps
"problems (run)" (testTargetProblemsRun config
)
141 , testCaseSteps
"problems (list-bin)" (testTargetProblemsListBin config
)
142 , testCaseSteps
"problems (test)" (testTargetProblemsTest config
)
143 , testCaseSteps
"problems (bench)" (testTargetProblemsBench config
)
144 , testCaseSteps
"problems (haddock)" (testTargetProblemsHaddock config
)
146 , testGroup
"Exceptions during building (local inplace)" $
147 [ testCase
"configure" (testExceptionInConfigureStep config
)
148 , testCase
"build" (testExceptionInBuildStep config
)
149 -- , testCase "register" testExceptionInRegisterStep
151 , -- TODO: need to repeat for packages for the store
152 -- TODO: need to check we can build sub-libs, foreign libs and exes
153 -- components for non-local packages / packages in the store.
155 testGroup
"Successful builds" $
156 [ testCaseSteps
"Setup script styles" (testSetupScriptStyles config
)
157 , testCase
"keep-going" (testBuildKeepGoing config
)
160 then -- disabled because https://github.com/haskell/cabal/issues/6272
163 [ testCase
"local tarball" (testBuildLocalTarball config
)
165 , testGroup
"Regression tests" $
166 [ testCase
"issue #3324" (testRegressionIssue3324 config
)
167 , testCase
"program options scope all" (testProgramOptionsAll config
)
168 , testCase
"program options scope local" (testProgramOptionsLocal config
)
169 , testCase
"program options scope specific" (testProgramOptionsSpecific config
)
171 , testGroup
"Flag tests" $
172 [ testCase
"Test Nix Flag" testNixFlags
173 , testCase
"Test Config options for commented options" testConfigOptionComments
174 , testCase
"Test Ignore Project Flag" testIgnoreProjectFlag
178 [ testCase
"dependencies" (testHaddockProjectDependencies config
)
182 testTargetSelectors
:: (String -> IO ()) -> Assertion
183 testTargetSelectors reportSubCase
= do
184 (_
, _
, _
, localPackages
, _
) <- configureProject testdir config
185 let readTargetSelectors
' =
186 readTargetSelectorsWith
193 Right ts
<- readTargetSelectors
' []
194 ts
@?
= [TargetPackage TargetImplicitCwd
["p-0.1"] Nothing
]
201 ts
@?
= replicate 2 (TargetAllPackages Nothing
)
203 reportSubCase
"filter"
221 [ TargetPackage TargetImplicitCwd
["p-0.1"] (Just kind
)
222 | kind
<- concatMap (replicate 2) [LibKind
..]
225 reportSubCase
"all:filter"
243 [ TargetAllPackages
(Just kind
)
244 | kind
<- concatMap (replicate 2) [LibKind
..]
262 @?
= replicate 4 (mkTargetPackage
"p-0.1")
263 ++ replicate 5 (mkTargetPackage
"q-0.1")
265 reportSubCase
"pkg:filter"
283 , ":pkg:p:benchmarks"
298 , ":pkg:q:benchmarks"
301 [ TargetPackage TargetExplicitNamed
["p-0.1"] (Just kind
)
302 | kind
<- concatMap (replicate 3) [LibKind
..]
304 ++ [ TargetPackage TargetExplicitNamed
["q-0.1"] (Just kind
)
305 | kind
<- concatMap (replicate 3) [LibKind
..]
308 reportSubCase
"component"
321 @?
= replicate 4 (TargetComponent
"p-0.1" (CLibName LMainLibName
) WholeComponent
)
322 ++ replicate 3 (TargetComponent
"q-0.1" (CLibName LMainLibName
) WholeComponent
)
324 reportSubCase
"module"
331 , ":pkg:p:lib:p:module:P"
335 , ":pkg:q:lib:q:module:QQ"
336 , "pexe:PMain" -- p:P or q:QQ would be ambiguous here
337 , "qexe:QMain" -- package p vs component p
340 @?
= replicate 4 (TargetComponent
"p-0.1" (CLibName LMainLibName
) (ModuleTarget
"P"))
341 ++ replicate 4 (TargetComponent
"q-0.1" (CLibName LMainLibName
) (ModuleTarget
"QQ"))
342 ++ [ TargetComponent
"p-0.1" (CExeName
"pexe") (ModuleTarget
"PMain")
343 , TargetComponent
"q-0.1" (CExeName
"qexe") (ModuleTarget
"QMain")
354 , ":pkg:p:lib:p:file:P.y"
359 , ":pkg:q:lib:q:file:QQ.y"
364 , ":pkg:q:lib:q:file:Q.y"
367 , "exe:ppexe:app/Main.hs"
368 , "p:ppexe:app/Main.hs"
369 , ":pkg:p:exe:ppexe:file:app/Main.hs"
372 , "exe:pppexe:a p p/Main.hs"
373 , "p:pppexe:a p p/Main.hs"
374 , ":pkg:p:exe:pppexe:file:a p p/Main.hs"
377 @?
= replicate 5 (TargetComponent
"p-0.1" (CLibName LMainLibName
) (FileTarget
"P"))
378 ++ replicate 5 (TargetComponent
"q-0.1" (CLibName LMainLibName
) (FileTarget
"QQ"))
379 ++ replicate 5 (TargetComponent
"q-0.1" (CLibName LMainLibName
) (FileTarget
"Q"))
380 ++ replicate 5 (TargetComponent
"p-0.1" (CExeName
"ppexe") (FileTarget
("app" </> "Main.hs")))
381 ++ replicate 5 (TargetComponent
"p-0.1" (CExeName
"pppexe") (FileTarget
("a p p" </> "Main.hs")))
382 -- Note there's a bit of an inconsistency here: for the single-part
383 -- syntax the target has to point to a file that exists, whereas for
384 -- all the other forms we don't require that.
388 testdir
= "targets/simple"
391 testTargetSelectorBadSyntax
:: Assertion
392 testTargetSelectorBadSyntax
= do
393 (_
, _
, _
, localPackages
, _
) <- configureProject testdir config
402 Left errs
<- readTargetSelectors localPackages Nothing targets
403 zipWithM_ (@?
=) errs
(map TargetSelectorUnrecognised targets
)
406 testdir
= "targets/empty"
409 testTargetSelectorAmbiguous
:: (String -> IO ()) -> Assertion
410 testTargetSelectorAmbiguous reportSubCase
= do
411 -- 'all' is ambiguous with packages and cwd components
412 reportSubCase
"ambiguous: all vs pkg"
415 [mkTargetPackage
"all", mkTargetAllPackages
]
418 reportSubCase
"ambiguous: all vs cwd component"
421 [mkTargetComponent
"other" (CExeName
"all"), mkTargetAllPackages
]
422 [mkpkg
"other" [mkexe
"all"]]
424 -- but 'all' is not ambiguous with non-cwd components, modules or files
425 reportSubCase
"unambiguous: all vs non-cwd comp, mod, file"
429 [ mkpkgAt
"foo" [mkexe
"All"] "foo"
432 [ mkexe
"bar" `withModules`
["All"]
433 , mkexe
"baz" `withCFiles`
["All"]
437 -- filters 'libs', 'exes' etc are ambiguous with packages and
439 reportSubCase
"ambiguous: cwd-pkg filter vs pkg"
442 [ mkTargetPackage
"libs"
443 , TargetPackage TargetImplicitCwd
["libs"] (Just LibKind
)
447 reportSubCase
"ambiguous: filter vs cwd component"
450 [ mkTargetComponent
"other" (CExeName
"exes")
451 , TargetPackage TargetImplicitCwd
["other"] (Just ExeKind
)
453 [mkpkg
"other" [mkexe
"exes"]]
455 -- but filters are not ambiguous with non-cwd components, modules or files
456 reportSubCase
"unambiguous: filter vs non-cwd comp, mod, file"
459 (TargetPackage TargetImplicitCwd
["bar"] (Just LibKind
))
460 [ mkpkgAt
"foo" [mkexe
"Libs"] "foo"
463 [ mkexe
"bar" `withModules`
["Libs"]
464 , mkexe
"baz" `withCFiles`
["Libs"]
468 -- local components shadow packages and other components
469 reportSubCase
"unambiguous: cwd comp vs pkg, non-cwd comp"
472 (mkTargetComponent
"other" (CExeName
"foo"))
473 [ mkpkg
"other" [mkexe
"foo"]
474 , mkpkgAt
"other2" [mkexe
"foo"] "other2" -- shadows non-local foo
475 , mkpkg
"foo" [] -- shadows package foo
478 -- local components shadow modules and files
479 reportSubCase
"unambiguous: cwd comp vs module, file"
482 (mkTargetComponent
"bar" (CExeName
"Foo"))
483 [ mkpkg
"bar" [mkexe
"Foo"]
486 [ mkexe
"other" `withModules`
["Foo"]
487 , mkexe
"other2" `withCFiles`
["Foo"]
491 -- packages shadow non-local components
492 reportSubCase
"unambiguous: pkg vs non-cwd comp"
495 (mkTargetPackage
"foo")
497 , mkpkgAt
"other" [mkexe
"foo"] "other" -- shadows non-local foo
500 -- packages shadow modules and files
501 reportSubCase
"unambiguous: pkg vs module, file"
504 (mkTargetPackage
"Foo")
505 [ mkpkgAt
"Foo" [] "foo"
508 [ mkexe
"other" `withModules`
["Foo"]
509 , mkexe
"other2" `withCFiles`
["Foo"]
513 -- File target is ambiguous, part of multiple components
514 reportSubCase
"ambiguous: file in multiple comps"
517 [ mkTargetFile
"foo" (CExeName
"bar") "Bar"
518 , mkTargetFile
"foo" (CExeName
"bar2") "Bar"
522 [ mkexe
"bar" `withModules`
["Bar"]
523 , mkexe
"bar2" `withModules`
["Bar"]
526 reportSubCase
"ambiguous: file in multiple comps with path"
529 [ mkTargetFile
"foo" (CExeName
"bar") ("src" </> "Bar")
530 , mkTargetFile
"foo" (CExeName
"bar2") ("src" </> "Bar")
534 [ mkexe
"bar" `withModules`
["Bar"] `withHsSrcDirs`
["src"]
535 , mkexe
"bar2" `withModules`
["Bar"] `withHsSrcDirs`
["src"]
539 -- non-exact case packages and components are ambiguous
540 reportSubCase
"ambiguous: non-exact-case pkg names"
543 [mkTargetPackage
"foo", mkTargetPackage
"FOO"]
544 [mkpkg
"foo" [], mkpkg
"FOO" []]
545 reportSubCase
"ambiguous: non-exact-case comp names"
548 [ mkTargetComponent
"bar" (CExeName
"foo")
549 , mkTargetComponent
"bar" (CExeName
"FOO")
551 [mkpkg
"bar" [mkexe
"foo", mkexe
"FOO"]]
553 -- exact-case Module or File over non-exact case package or component
554 reportSubCase
"unambiguous: module vs non-exact-case pkg, comp"
557 (mkTargetModule
"other" (CExeName
"other") "Baz")
558 [ mkpkg
"baz" [mkexe
"BAZ"]
559 , mkpkg
"other" [mkexe
"other" `withModules`
["Baz"]]
561 reportSubCase
"unambiguous: file vs non-exact-case pkg, comp"
564 (mkTargetFile
"other" (CExeName
"other") "Baz")
565 [ mkpkg
"baz" [mkexe
"BAZ"]
566 , mkpkg
"other" [mkexe
"other" `withCFiles`
["Baz"]]
572 -> [SourcePackage
(PackageLocation a
)]
574 assertAmbiguous str tss pkgs
= do
576 readTargetSelectorsWith
578 (map SpecificSourcePackage pkgs
)
582 Left
[TargetSelectorAmbiguous _ tss
'] ->
583 sort (map snd tss
') @?
= sort tss
586 "expected Left [TargetSelectorAmbiguous _ _], "
593 -> [SourcePackage
(PackageLocation a
)]
595 assertUnambiguous str ts pkgs
= do
597 readTargetSelectorsWith
599 (map SpecificSourcePackage pkgs
)
603 Right
[ts
'] -> ts
' @?
= ts
606 "expected Right [Target...], "
612 { TS
.doesFileExist = \_p
-> return True
613 , TS
.doesDirectoryExist = \_p
-> return True
614 , TS
.canonicalizePath
= \p
-> return ("/" </> p
) -- FilePath.Unix.</> ?
615 , TS
.getCurrentDirectory = return "/"
618 mkpkg
:: String -> [Executable
] -> SourcePackage
(PackageLocation a
)
619 mkpkg pkgidstr exes
= mkpkgAt pkgidstr exes
""
625 -> SourcePackage
(PackageLocation a
)
626 mkpkgAt pkgidstr exes loc
=
628 { srcpkgPackageId
= pkgid
629 , srcpkgSource
= LocalUnpackedPackage loc
630 , srcpkgDescrOverride
= Nothing
631 , srcpkgDescription
=
632 GenericPackageDescription
633 { packageDescription
= emptyPackageDescription
{package
= pkgid
}
634 , gpdScannedVersion
= Nothing
635 , genPackageFlags
= []
636 , condLibrary
= Nothing
637 , condSubLibraries
= []
638 , condForeignLibs
= []
640 [ (exeName exe
, CondNode exe
[] [])
643 , condTestSuites
= []
644 , condBenchmarks
= []
648 pkgid
= fromMaybe (error $ "failed to parse " ++ pkgidstr
) $ simpleParse pkgidstr
650 mkexe
:: String -> Executable
651 mkexe name
= mempty
{exeName
= fromString name
}
653 withModules
:: Executable
-> [String] -> Executable
654 withModules exe mods
=
655 exe
{buildInfo
= (buildInfo exe
){otherModules
= map fromString mods
}}
657 withCFiles
:: Executable
-> [FilePath] -> Executable
658 withCFiles exe files
=
659 exe
{buildInfo
= (buildInfo exe
){cSources
= map unsafeMakeSymbolicPath files
}}
661 withHsSrcDirs
:: Executable
-> [FilePath] -> Executable
662 withHsSrcDirs exe srcDirs
=
663 exe
{buildInfo
= (buildInfo exe
){hsSourceDirs
= map unsafeMakeSymbolicPath srcDirs
}}
665 mkTargetPackage
:: PackageId
-> TargetSelector
666 mkTargetPackage pkgid
=
667 TargetPackage TargetExplicitNamed
[pkgid
] Nothing
669 mkTargetComponent
:: PackageId
-> ComponentName
-> TargetSelector
670 mkTargetComponent pkgid cname
=
671 TargetComponent pkgid cname WholeComponent
673 mkTargetModule
:: PackageId
-> ComponentName
-> ModuleName
-> TargetSelector
674 mkTargetModule pkgid cname mname
=
675 TargetComponent pkgid cname
(ModuleTarget mname
)
677 mkTargetFile
:: PackageId
-> ComponentName
-> String -> TargetSelector
678 mkTargetFile pkgid cname fname
=
679 TargetComponent pkgid cname
(FileTarget fname
)
681 mkTargetAllPackages
:: TargetSelector
682 mkTargetAllPackages
= TargetAllPackages Nothing
684 instance IsString PackageIdentifier
where
685 fromString pkgidstr
= pkgid
687 pkgid
= fromMaybe (error $ "fromString @PackageIdentifier " ++ show pkgidstr
) $ simpleParse pkgidstr
689 testTargetSelectorNoCurrentPackage
:: Assertion
690 testTargetSelectorNoCurrentPackage
= do
691 (_
, _
, _
, localPackages
, _
) <- configureProject testdir config
692 let readTargetSelectors
' =
693 readTargetSelectorsWith
709 Left errs
<- readTargetSelectors
' targets
713 [ TargetSelectorNoCurrentPackage ts
715 , let ts
= fromMaybe (error $ "failed to parse target string " ++ target
) $ parseTargetString target
719 testdir
= "targets/complex"
722 testTargetSelectorNoTargets
:: Assertion
723 testTargetSelectorNoTargets
= do
724 (_
, _
, _
, localPackages
, _
) <- configureProject testdir config
725 Left errs
<- readTargetSelectors localPackages Nothing
[]
726 errs
@?
= [TargetSelectorNoTargetsInCwd
True]
729 testdir
= "targets/complex"
732 testTargetSelectorProjectEmpty
:: Assertion
733 testTargetSelectorProjectEmpty
= do
734 (_
, _
, _
, localPackages
, _
) <- configureProject testdir config
735 Left errs
<- readTargetSelectors localPackages Nothing
[]
736 errs
@?
= [TargetSelectorNoTargetsInProject
]
739 testdir
= "targets/empty"
742 -- | Ensure we don't miss primary package and produce
743 -- TargetSelectorNoTargetsInCwd error due to symlink or
744 -- drive capitalisation mismatch when no targets are given
745 testTargetSelectorCanonicalizedPath
:: Assertion
746 testTargetSelectorCanonicalizedPath
= do
747 (_
, _
, _
, localPackages
, _
) <- configureProject testdir config
748 cwd
<- getCurrentDirectory
749 let virtcwd
= cwd
</> basedir
</> symlink
750 -- Check that the symlink is there before running test as on Windows
751 -- some versions/configurations of git won't pull down/create the symlink
752 canRunTest
<- doesDirectoryExist virtcwd
756 let dirActions
' = (dirActions symlink
){TS
.getCurrentDirectory = return virtcwd
}
757 Right ts
<- readTargetSelectorsWith dirActions
' localPackages Nothing
[]
758 ts
@?
= [TargetPackage TargetImplicitCwd
["p-0.1"] Nothing
]
762 testdir
= "targets/simple"
763 symlink
= "targets/symbolic-link-to-simple"
766 testTargetProblemsCommon
:: ProjectConfig
-> Assertion
767 testTargetProblemsCommon config0
= do
768 (_
, elaboratedPlan
, _
) <- planProject testdir config
770 let pkgIdMap
:: Map
.Map PackageName PackageId
773 [ (packageName p
, packageId p
)
774 | p
<- InstallPlan
.toList elaboratedPlan
778 :: [ ( TargetSelector
-> TargetProblem
'
783 [ -- Cannot resolve packages outside of the project
785 ( \_
-> TargetProblemNoSuchPackage
"foobar"
786 , mkTargetPackage
"foobar"
788 , -- We cannot currently build components like testsuites or
789 -- benchmarks from packages that are not local to the project
792 TargetComponentNotProjectLocal
793 (pkgIdMap Map
.! "filepath")
794 (CTestName
"filepath-tests")
797 (pkgIdMap Map
.! "filepath")
798 (CTestName
"filepath-tests")
800 , -- Components can be explicitly @buildable: False@
802 ( \_
-> TargetComponentNotBuildable
"q-0.1" (CExeName
"buildable-false") WholeComponent
803 , mkTargetComponent
"q-0.1" (CExeName
"buildable-false")
805 , -- Testsuites and benchmarks can be disabled by the solver if it
806 -- cannot satisfy deps
808 ( \_
-> TargetOptionalStanzaDisabledBySolver
"q-0.1" (CTestName
"solver-disabled") WholeComponent
809 , mkTargetComponent
"q-0.1" (CTestName
"solver-disabled")
811 , -- Testsuites and benchmarks can be disabled explicitly by the
815 TargetOptionalStanzaDisabledByUser
817 (CBenchName
"user-disabled")
819 , mkTargetComponent
"q-0.1" (CBenchName
"user-disabled")
821 , -- An unknown package. The target selector resolution should only
822 -- produce known packages, so this should not happen with the
823 -- output from 'readTargetSelectors'.
825 ( \_
-> TargetProblemNoSuchPackage
"foobar"
826 , mkTargetPackage
"foobar"
828 , -- An unknown component of a known package. The target selector
829 -- resolution should only produce known packages, so this should
830 -- not happen with the output from 'readTargetSelectors'.
832 ( \_
-> TargetProblemNoSuchComponent
"q-0.1" (CExeName
"no-such")
833 , mkTargetComponent
"q-0.1" (CExeName
"no-such")
838 CmdBuild
.selectPackageTargets
839 CmdBuild
.selectComponentTarget
842 testdir
= "targets/complex"
845 { projectConfigLocalPackages
=
846 (projectConfigLocalPackages config0
)
847 { packageConfigBenchmarks
= toFlag
False
849 , projectConfigShared
=
850 (projectConfigShared config0
)
851 { projectConfigConstraints
=
853 ( UserConstraint
(UserAnyQualifier
"filepath") PackagePropertySource
854 , ConstraintSourceUnknown
860 testTargetProblemsBuild
:: ProjectConfig
-> (String -> IO ()) -> Assertion
861 testTargetProblemsBuild config reportSubCase
= do
862 reportSubCase
"empty-pkg"
863 assertProjectTargetProblems
866 CmdBuild
.selectPackageTargets
867 CmdBuild
.selectComponentTarget
868 [ (TargetProblemNoTargets
, mkTargetPackage
"p-0.1")
871 reportSubCase
"all-disabled"
872 assertProjectTargetProblems
873 "targets/all-disabled"
875 { projectConfigLocalPackages
=
876 (projectConfigLocalPackages config
)
877 { packageConfigBenchmarks
= toFlag
False
880 CmdBuild
.selectPackageTargets
881 CmdBuild
.selectComponentTarget
884 TargetProblemNoneEnabled
887 (CBenchName
"user-disabled")
892 (CTestName
"solver-disabled")
893 TargetDisabledBySolver
897 (CExeName
"buildable-false")
902 (CLibName LMainLibName
)
906 , mkTargetPackage
"p-0.1"
910 reportSubCase
"enabled component kinds"
911 -- When we explicitly enable all the component kinds then selecting the
912 -- whole package selects those component kinds too
914 (_
, elaboratedPlan
, _
) <-
918 { projectConfigLocalPackages
=
919 (projectConfigLocalPackages config
)
920 { packageConfigTests
= toFlag
True
921 , packageConfigBenchmarks
= toFlag
True
924 assertProjectDistinctTargets
926 CmdBuild
.selectPackageTargets
927 CmdBuild
.selectComponentTarget
928 [mkTargetPackage
"p-0.1"]
929 [ ("p-0.1-inplace", (CLibName LMainLibName
))
930 , ("p-0.1-inplace-a-benchmark", CBenchName
"a-benchmark")
931 , ("p-0.1-inplace-a-testsuite", CTestName
"a-testsuite")
932 , ("p-0.1-inplace-an-exe", CExeName
"an-exe")
933 , ("p-0.1-inplace-libp", CFLibName
"libp")
936 reportSubCase
"disabled component kinds"
937 -- When we explicitly disable all the component kinds then selecting the
938 -- whole package only selects the library, foreign lib and exes
940 (_
, elaboratedPlan
, _
) <-
944 { projectConfigLocalPackages
=
945 (projectConfigLocalPackages config
)
946 { packageConfigTests
= toFlag
False
947 , packageConfigBenchmarks
= toFlag
False
950 assertProjectDistinctTargets
952 CmdBuild
.selectPackageTargets
953 CmdBuild
.selectComponentTarget
954 [mkTargetPackage
"p-0.1"]
955 [ ("p-0.1-inplace", (CLibName LMainLibName
))
956 , ("p-0.1-inplace-an-exe", CExeName
"an-exe")
957 , ("p-0.1-inplace-libp", CFLibName
"libp")
960 reportSubCase
"requested component kinds"
961 -- When we selecting the package with an explicit filter then we get those
962 -- components even though we did not explicitly enable tests/benchmarks
964 (_
, elaboratedPlan
, _
) <- planProject
"targets/variety" config
965 assertProjectDistinctTargets
967 CmdBuild
.selectPackageTargets
968 CmdBuild
.selectComponentTarget
969 [ TargetPackage TargetExplicitNamed
["p-0.1"] (Just TestKind
)
970 , TargetPackage TargetExplicitNamed
["p-0.1"] (Just BenchKind
)
972 [ ("p-0.1-inplace-a-benchmark", CBenchName
"a-benchmark")
973 , ("p-0.1-inplace-a-testsuite", CTestName
"a-testsuite")
976 testTargetProblemsRepl
:: ProjectConfig
-> (String -> IO ()) -> Assertion
977 testTargetProblemsRepl config reportSubCase
= do
978 reportSubCase
"multiple-libs"
979 assertProjectTargetProblems
980 "targets/multiple-libs"
982 (CmdRepl
.selectPackageTargets
(CmdRepl
.MultiReplDecision Nothing
False))
983 CmdRepl
.selectComponentTarget
986 (CmdRepl
.matchesMultipleProblem
(CmdRepl
.MultiReplDecision Nothing
False))
989 (CLibName LMainLibName
)
990 (TargetBuildable
() TargetRequestedByDefault
)
994 (CLibName LMainLibName
)
995 (TargetBuildable
() TargetRequestedByDefault
)
998 , mkTargetAllPackages
1002 reportSubCase
"multiple-exes"
1003 assertProjectTargetProblems
1004 "targets/multiple-exes"
1006 (CmdRepl
.selectPackageTargets
(CmdRepl
.MultiReplDecision Nothing
False))
1007 CmdRepl
.selectComponentTarget
1010 (CmdRepl
.matchesMultipleProblem
(CmdRepl
.MultiReplDecision Nothing
False))
1014 (TargetBuildable
() TargetRequestedByDefault
)
1019 (TargetBuildable
() TargetRequestedByDefault
)
1022 , mkTargetPackage
"p-0.1"
1026 reportSubCase
"multiple-tests"
1027 assertProjectTargetProblems
1028 "targets/multiple-tests"
1030 (CmdRepl
.selectPackageTargets
(CmdRepl
.MultiReplDecision Nothing
False))
1031 CmdRepl
.selectComponentTarget
1034 (CmdRepl
.matchesMultipleProblem
(CmdRepl
.MultiReplDecision Nothing
False))
1038 (TargetBuildable
() TargetNotRequestedByDefault
)
1043 (TargetBuildable
() TargetNotRequestedByDefault
)
1046 , TargetPackage TargetExplicitNamed
["p-0.1"] (Just TestKind
)
1050 reportSubCase
"multiple targets"
1052 (_
, elaboratedPlan
, _
) <- planProject
"targets/multiple-exes" config
1053 assertProjectDistinctTargets
1055 (CmdRepl
.selectPackageTargets
(CmdRepl
.MultiReplDecision Nothing
False))
1056 CmdRepl
.selectComponentTarget
1057 [ mkTargetComponent
"p-0.1" (CExeName
"p1")
1058 , mkTargetComponent
"p-0.1" (CExeName
"p2")
1060 [ ("p-0.1-inplace-p1", CExeName
"p1")
1061 , ("p-0.1-inplace-p2", CExeName
"p2")
1064 reportSubCase
"libs-disabled"
1065 assertProjectTargetProblems
1066 "targets/libs-disabled"
1068 (CmdRepl
.selectPackageTargets
(CmdRepl
.MultiReplDecision Nothing
False))
1069 CmdRepl
.selectComponentTarget
1072 TargetProblemNoneEnabled
1073 [AvailableTarget
"p-0.1" (CLibName LMainLibName
) TargetNotBuildable
True]
1074 , mkTargetPackage
"p-0.1"
1078 reportSubCase
"exes-disabled"
1079 assertProjectTargetProblems
1080 "targets/exes-disabled"
1082 (CmdRepl
.selectPackageTargets
(CmdRepl
.MultiReplDecision Nothing
False))
1083 CmdRepl
.selectComponentTarget
1086 TargetProblemNoneEnabled
1087 [ AvailableTarget
"p-0.1" (CExeName
"p") TargetNotBuildable
True
1089 , mkTargetPackage
"p-0.1"
1093 reportSubCase
"test-only"
1094 assertProjectTargetProblems
1097 (CmdRepl
.selectPackageTargets
(CmdRepl
.MultiReplDecision Nothing
False))
1098 CmdRepl
.selectComponentTarget
1101 TargetProblemNoneEnabled
1105 (TargetBuildable
() TargetNotRequestedByDefault
)
1108 , mkTargetPackage
"p-0.1"
1112 reportSubCase
"empty-pkg"
1113 assertProjectTargetProblems
1116 (CmdRepl
.selectPackageTargets
(CmdRepl
.MultiReplDecision Nothing
False))
1117 CmdRepl
.selectComponentTarget
1118 [ (TargetProblemNoTargets
, mkTargetPackage
"p-0.1")
1121 reportSubCase
"requested component kinds"
1123 (_
, elaboratedPlan
, _
) <- planProject
"targets/variety" config
1124 -- by default we only get the lib
1125 assertProjectDistinctTargets
1127 (CmdRepl
.selectPackageTargets
(CmdRepl
.MultiReplDecision Nothing
False))
1128 CmdRepl
.selectComponentTarget
1129 [TargetPackage TargetExplicitNamed
["p-0.1"] Nothing
]
1130 [("p-0.1-inplace", (CLibName LMainLibName
))]
1131 -- When we select the package with an explicit filter then we get those
1132 -- components even though we did not explicitly enable tests/benchmarks
1133 assertProjectDistinctTargets
1135 (CmdRepl
.selectPackageTargets
(CmdRepl
.MultiReplDecision Nothing
False))
1136 CmdRepl
.selectComponentTarget
1137 [TargetPackage TargetExplicitNamed
["p-0.1"] (Just TestKind
)]
1138 [("p-0.1-inplace-a-testsuite", CTestName
"a-testsuite")]
1139 assertProjectDistinctTargets
1141 (CmdRepl
.selectPackageTargets
(CmdRepl
.MultiReplDecision Nothing
False))
1142 CmdRepl
.selectComponentTarget
1143 [TargetPackage TargetExplicitNamed
["p-0.1"] (Just BenchKind
)]
1144 [("p-0.1-inplace-a-benchmark", CBenchName
"a-benchmark")]
1146 testTargetProblemsListBin
:: ProjectConfig
-> (String -> IO ()) -> Assertion
1147 testTargetProblemsListBin config reportSubCase
= do
1148 reportSubCase
"one-of-each"
1150 (_
, elaboratedPlan
, _
) <- planProject
"targets/one-of-each" config
1151 assertProjectDistinctTargets
1153 CmdListBin
.selectPackageTargets
1154 CmdListBin
.selectComponentTarget
1155 [ TargetPackage TargetExplicitNamed
["p-0.1"] Nothing
1157 [ ("p-0.1-inplace-p1", CExeName
"p1")
1160 reportSubCase
"multiple-exes"
1161 assertProjectTargetProblems
1162 "targets/multiple-exes"
1164 CmdListBin
.selectPackageTargets
1165 CmdListBin
.selectComponentTarget
1168 CmdListBin
.matchesMultipleProblem
1172 (TargetBuildable
() TargetRequestedByDefault
)
1177 (TargetBuildable
() TargetRequestedByDefault
)
1180 , mkTargetPackage
"p-0.1"
1184 reportSubCase
"multiple targets"
1186 (_
, elaboratedPlan
, _
) <- planProject
"targets/multiple-exes" config
1187 assertProjectDistinctTargets
1189 CmdListBin
.selectPackageTargets
1190 CmdListBin
.selectComponentTarget
1191 [ mkTargetComponent
"p-0.1" (CExeName
"p1")
1192 , mkTargetComponent
"p-0.1" (CExeName
"p2")
1194 [ ("p-0.1-inplace-p1", CExeName
"p1")
1195 , ("p-0.1-inplace-p2", CExeName
"p2")
1198 reportSubCase
"exes-disabled"
1199 assertProjectTargetProblems
1200 "targets/exes-disabled"
1202 CmdListBin
.selectPackageTargets
1203 CmdListBin
.selectComponentTarget
1206 TargetProblemNoneEnabled
1207 [ AvailableTarget
"p-0.1" (CExeName
"p") TargetNotBuildable
True
1209 , mkTargetPackage
"p-0.1"
1213 reportSubCase
"empty-pkg"
1214 assertProjectTargetProblems
1217 CmdListBin
.selectPackageTargets
1218 CmdListBin
.selectComponentTarget
1219 [ (TargetProblemNoTargets
, mkTargetPackage
"p-0.1")
1222 reportSubCase
"lib-only"
1223 assertProjectTargetProblems
1226 CmdListBin
.selectPackageTargets
1227 CmdListBin
.selectComponentTarget
1228 [ (CmdListBin
.noComponentsProblem
, mkTargetPackage
"p-0.1")
1231 testTargetProblemsRun
:: ProjectConfig
-> (String -> IO ()) -> Assertion
1232 testTargetProblemsRun config reportSubCase
= do
1233 reportSubCase
"one-of-each"
1235 (_
, elaboratedPlan
, _
) <- planProject
"targets/one-of-each" config
1236 assertProjectDistinctTargets
1238 CmdRun
.selectPackageTargets
1239 CmdRun
.selectComponentTarget
1240 [ TargetPackage TargetExplicitNamed
["p-0.1"] Nothing
1242 [ ("p-0.1-inplace-p1", CExeName
"p1")
1245 reportSubCase
"multiple-exes"
1246 assertProjectTargetProblems
1247 "targets/multiple-exes"
1249 CmdRun
.selectPackageTargets
1250 CmdRun
.selectComponentTarget
1253 CmdRun
.matchesMultipleProblem
1257 (TargetBuildable
() TargetRequestedByDefault
)
1262 (TargetBuildable
() TargetRequestedByDefault
)
1265 , mkTargetPackage
"p-0.1"
1269 reportSubCase
"multiple targets"
1271 (_
, elaboratedPlan
, _
) <- planProject
"targets/multiple-exes" config
1272 assertProjectDistinctTargets
1274 CmdRun
.selectPackageTargets
1275 CmdRun
.selectComponentTarget
1276 [ mkTargetComponent
"p-0.1" (CExeName
"p1")
1277 , mkTargetComponent
"p-0.1" (CExeName
"p2")
1279 [ ("p-0.1-inplace-p1", CExeName
"p1")
1280 , ("p-0.1-inplace-p2", CExeName
"p2")
1283 reportSubCase
"exes-disabled"
1284 assertProjectTargetProblems
1285 "targets/exes-disabled"
1287 CmdRun
.selectPackageTargets
1288 CmdRun
.selectComponentTarget
1291 TargetProblemNoneEnabled
1292 [ AvailableTarget
"p-0.1" (CExeName
"p") TargetNotBuildable
True
1294 , mkTargetPackage
"p-0.1"
1298 reportSubCase
"empty-pkg"
1299 assertProjectTargetProblems
1302 CmdRun
.selectPackageTargets
1303 CmdRun
.selectComponentTarget
1304 [ (TargetProblemNoTargets
, mkTargetPackage
"p-0.1")
1307 reportSubCase
"lib-only"
1308 assertProjectTargetProblems
1311 CmdRun
.selectPackageTargets
1312 CmdRun
.selectComponentTarget
1313 [ (CmdRun
.noExesProblem
, mkTargetPackage
"p-0.1")
1316 testTargetProblemsTest
:: ProjectConfig
-> (String -> IO ()) -> Assertion
1317 testTargetProblemsTest config reportSubCase
= do
1318 reportSubCase
"disabled by config"
1319 assertProjectTargetProblems
1320 "targets/tests-disabled"
1322 { projectConfigLocalPackages
=
1323 (projectConfigLocalPackages config
)
1324 { packageConfigTests
= toFlag
False
1327 CmdTest
.selectPackageTargets
1328 CmdTest
.selectComponentTarget
1331 TargetProblemNoneEnabled
1334 (CTestName
"user-disabled")
1335 TargetDisabledByUser
1339 (CTestName
"solver-disabled")
1340 TargetDisabledByUser
1343 , mkTargetPackage
"p-0.1"
1347 reportSubCase
"disabled by solver & buildable false"
1348 assertProjectTargetProblems
1349 "targets/tests-disabled"
1351 CmdTest
.selectPackageTargets
1352 CmdTest
.selectComponentTarget
1355 TargetProblemNoneEnabled
1358 (CTestName
"user-disabled")
1359 TargetDisabledBySolver
1363 (CTestName
"solver-disabled")
1364 TargetDisabledBySolver
1367 , mkTargetPackage
"p-0.1"
1371 TargetProblemNoneEnabled
1374 (CTestName
"buildable-false")
1378 , mkTargetPackage
"q-0.1"
1382 reportSubCase
"empty-pkg"
1383 assertProjectTargetProblems
1386 CmdTest
.selectPackageTargets
1387 CmdTest
.selectComponentTarget
1388 [ (TargetProblemNoTargets
, mkTargetPackage
"p-0.1")
1391 reportSubCase
"no tests"
1392 assertProjectTargetProblems
1395 CmdTest
.selectPackageTargets
1396 CmdTest
.selectComponentTarget
1397 [ (CmdTest
.noTestsProblem
, mkTargetPackage
"p-0.1")
1398 , (CmdTest
.noTestsProblem
, mkTargetPackage
"q-0.1")
1401 reportSubCase
"not a test"
1402 assertProjectTargetProblems
1405 CmdTest
.selectPackageTargets
1406 CmdTest
.selectComponentTarget
1409 ( CmdTest
.notTestProblem
1411 (CLibName LMainLibName
)
1413 , mkTargetComponent
"p-0.1" (CLibName LMainLibName
)
1417 ( CmdTest
.notTestProblem
1421 , mkTargetComponent
"p-0.1" (CExeName
"an-exe")
1425 ( CmdTest
.notTestProblem
1429 , mkTargetComponent
"p-0.1" (CFLibName
"libp")
1433 ( CmdTest
.notTestProblem
1435 (CBenchName
"a-benchmark")
1437 , mkTargetComponent
"p-0.1" (CBenchName
"a-benchmark")
1441 ( CmdTest
.isSubComponentProblem
1444 (ModuleTarget modname
)
1446 , mkTargetModule
"p-0.1" cname modname
1448 |
(cname
, modname
) <-
1449 [ (CTestName
"a-testsuite", "TestModule")
1450 , (CBenchName
"a-benchmark", "BenchModule")
1451 , (CExeName
"an-exe", "ExeModule")
1452 , ((CLibName LMainLibName
), "P")
1456 ( CmdTest
.isSubComponentProblem
1461 , mkTargetFile
"p-0.1" cname fname
1464 [ (CTestName
"a-testsuite", "Test.hs")
1465 , (CBenchName
"a-benchmark", "Bench.hs")
1466 , (CExeName
"an-exe", "Main.hs")
1470 testTargetProblemsBench
:: ProjectConfig
-> (String -> IO ()) -> Assertion
1471 testTargetProblemsBench config reportSubCase
= do
1472 reportSubCase
"disabled by config"
1473 assertProjectTargetProblems
1474 "targets/benchmarks-disabled"
1476 { projectConfigLocalPackages
=
1477 (projectConfigLocalPackages config
)
1478 { packageConfigBenchmarks
= toFlag
False
1481 CmdBench
.selectPackageTargets
1482 CmdBench
.selectComponentTarget
1485 TargetProblemNoneEnabled
1488 (CBenchName
"user-disabled")
1489 TargetDisabledByUser
1493 (CBenchName
"solver-disabled")
1494 TargetDisabledByUser
1497 , mkTargetPackage
"p-0.1"
1501 reportSubCase
"disabled by solver & buildable false"
1502 assertProjectTargetProblems
1503 "targets/benchmarks-disabled"
1505 CmdBench
.selectPackageTargets
1506 CmdBench
.selectComponentTarget
1509 TargetProblemNoneEnabled
1512 (CBenchName
"user-disabled")
1513 TargetDisabledBySolver
1517 (CBenchName
"solver-disabled")
1518 TargetDisabledBySolver
1521 , mkTargetPackage
"p-0.1"
1525 TargetProblemNoneEnabled
1528 (CBenchName
"buildable-false")
1532 , mkTargetPackage
"q-0.1"
1536 reportSubCase
"empty-pkg"
1537 assertProjectTargetProblems
1540 CmdBench
.selectPackageTargets
1541 CmdBench
.selectComponentTarget
1542 [ (TargetProblemNoTargets
, mkTargetPackage
"p-0.1")
1545 reportSubCase
"no benchmarks"
1546 assertProjectTargetProblems
1549 CmdBench
.selectPackageTargets
1550 CmdBench
.selectComponentTarget
1551 [ (CmdBench
.noBenchmarksProblem
, mkTargetPackage
"p-0.1")
1552 , (CmdBench
.noBenchmarksProblem
, mkTargetPackage
"q-0.1")
1555 reportSubCase
"not a benchmark"
1556 assertProjectTargetProblems
1559 CmdBench
.selectPackageTargets
1560 CmdBench
.selectComponentTarget
1563 ( CmdBench
.componentNotBenchmarkProblem
1565 (CLibName LMainLibName
)
1567 , mkTargetComponent
"p-0.1" (CLibName LMainLibName
)
1571 ( CmdBench
.componentNotBenchmarkProblem
1575 , mkTargetComponent
"p-0.1" (CExeName
"an-exe")
1579 ( CmdBench
.componentNotBenchmarkProblem
1583 , mkTargetComponent
"p-0.1" (CFLibName
"libp")
1587 ( CmdBench
.componentNotBenchmarkProblem
1589 (CTestName
"a-testsuite")
1591 , mkTargetComponent
"p-0.1" (CTestName
"a-testsuite")
1595 ( CmdBench
.isSubComponentProblem
1598 (ModuleTarget modname
)
1600 , mkTargetModule
"p-0.1" cname modname
1602 |
(cname
, modname
) <-
1603 [ (CTestName
"a-testsuite", "TestModule")
1604 , (CBenchName
"a-benchmark", "BenchModule")
1605 , (CExeName
"an-exe", "ExeModule")
1606 , ((CLibName LMainLibName
), "P")
1610 ( CmdBench
.isSubComponentProblem
1615 , mkTargetFile
"p-0.1" cname fname
1618 [ (CTestName
"a-testsuite", "Test.hs")
1619 , (CBenchName
"a-benchmark", "Bench.hs")
1620 , (CExeName
"an-exe", "Main.hs")
1624 testTargetProblemsHaddock
:: ProjectConfig
-> (String -> IO ()) -> Assertion
1625 testTargetProblemsHaddock config reportSubCase
= do
1626 reportSubCase
"all-disabled"
1627 assertProjectTargetProblems
1628 "targets/all-disabled"
1630 ( let haddockFlags
= mkHaddockFlags
False True True False
1631 in CmdHaddock
.selectPackageTargets haddockFlags
1633 CmdHaddock
.selectComponentTarget
1636 TargetProblemNoneEnabled
1639 (CBenchName
"user-disabled")
1640 TargetDisabledByUser
1644 (CTestName
"solver-disabled")
1645 TargetDisabledBySolver
1649 (CExeName
"buildable-false")
1654 (CLibName LMainLibName
)
1658 , mkTargetPackage
"p-0.1"
1662 reportSubCase
"empty-pkg"
1663 assertProjectTargetProblems
1666 ( let haddockFlags
= mkHaddockFlags
False False False False
1667 in CmdHaddock
.selectPackageTargets haddockFlags
1669 CmdHaddock
.selectComponentTarget
1670 [ (TargetProblemNoTargets
, mkTargetPackage
"p-0.1")
1673 reportSubCase
"enabled component kinds"
1674 -- When we explicitly enable all the component kinds then selecting the
1675 -- whole package selects those component kinds too
1676 (_
, elaboratedPlan
, _
) <- planProject
"targets/variety" config
1677 let haddockFlags
= mkHaddockFlags
True True True True
1678 in assertProjectDistinctTargets
1680 (CmdHaddock
.selectPackageTargets haddockFlags
)
1681 CmdHaddock
.selectComponentTarget
1682 [mkTargetPackage
"p-0.1"]
1683 [ ("p-0.1-inplace", (CLibName LMainLibName
))
1684 , ("p-0.1-inplace-a-benchmark", CBenchName
"a-benchmark")
1685 , ("p-0.1-inplace-a-testsuite", CTestName
"a-testsuite")
1686 , ("p-0.1-inplace-an-exe", CExeName
"an-exe")
1687 , ("p-0.1-inplace-libp", CFLibName
"libp")
1690 reportSubCase
"disabled component kinds"
1691 -- When we explicitly disable all the component kinds then selecting the
1692 -- whole package only selects the library
1693 let haddockFlags
= mkHaddockFlags
False False False False
1694 in assertProjectDistinctTargets
1696 (CmdHaddock
.selectPackageTargets haddockFlags
)
1697 CmdHaddock
.selectComponentTarget
1698 [mkTargetPackage
"p-0.1"]
1699 [("p-0.1-inplace", (CLibName LMainLibName
))]
1701 reportSubCase
"requested component kinds"
1702 -- When we selecting the package with an explicit filter then it does not
1703 -- matter if the config was to disable all the component kinds
1704 let haddockFlags
= mkHaddockFlags
False False False False
1705 in assertProjectDistinctTargets
1707 (CmdHaddock
.selectPackageTargets haddockFlags
)
1708 CmdHaddock
.selectComponentTarget
1709 [ TargetPackage TargetExplicitNamed
["p-0.1"] (Just FLibKind
)
1710 , TargetPackage TargetExplicitNamed
["p-0.1"] (Just ExeKind
)
1711 , TargetPackage TargetExplicitNamed
["p-0.1"] (Just TestKind
)
1712 , TargetPackage TargetExplicitNamed
["p-0.1"] (Just BenchKind
)
1714 [ ("p-0.1-inplace-a-benchmark", CBenchName
"a-benchmark")
1715 , ("p-0.1-inplace-a-testsuite", CTestName
"a-testsuite")
1716 , ("p-0.1-inplace-an-exe", CExeName
"an-exe")
1717 , ("p-0.1-inplace-libp", CFLibName
"libp")
1720 mkHaddockFlags flib exe test bench
=
1722 { haddockForeignLibs
= toFlag flib
1723 , haddockExecutables
= toFlag exe
1724 , haddockTestSuites
= toFlag test
1725 , haddockBenchmarks
= toFlag bench
1728 assertProjectDistinctTargets
1730 . (Eq err
, Show err
)
1731 => ElaboratedInstallPlan
1732 -> (forall k
. TargetSelector
-> [AvailableTarget k
] -> Either (TargetProblem err
) [k
])
1733 -> (forall k
. SubComponentTarget
-> AvailableTarget k
-> Either (TargetProblem err
) k
)
1735 -> [(UnitId
, ComponentName
)]
1737 assertProjectDistinctTargets
1739 selectPackageTargets
1740 selectComponentTarget
1743 | Right targets
<- results
=
1744 distinctTargetComponents targets
@?
= Set
.fromList expectedTargets
1747 "assertProjectDistinctTargets: expected "
1748 ++ "(Right targets) but got "
1753 selectPackageTargets
1754 selectComponentTarget
1759 assertProjectTargetProblems
1761 . (Eq err
, Show err
)
1766 -> [AvailableTarget k
]
1767 -> Either (TargetProblem err
) [k
]
1770 . SubComponentTarget
1771 -> AvailableTarget k
1772 -> Either (TargetProblem err
) k
1774 -> [(TargetSelector
-> TargetProblem err
, TargetSelector
)]
1776 assertProjectTargetProblems
1779 selectPackageTargets
1780 selectComponentTarget
1782 (_
, elaboratedPlan
, _
) <- planProject testdir config
1783 assertTargetProblems
1785 selectPackageTargets
1786 selectComponentTarget
1789 assertTargetProblems
1791 . (Eq err
, Show err
)
1792 => ElaboratedInstallPlan
1793 -> (forall k
. TargetSelector
-> [AvailableTarget k
] -> Either (TargetProblem err
) [k
])
1794 -> (forall k
. SubComponentTarget
-> AvailableTarget k
-> Either (TargetProblem err
) k
)
1795 -> [(TargetSelector
-> TargetProblem err
, TargetSelector
)]
1797 assertTargetProblems elaboratedPlan selectPackageTargets selectComponentTarget
=
1798 mapM_ (uncurry assertTargetProblem
)
1800 assertTargetProblem expected targetSelector
=
1803 selectPackageTargets
1804 selectComponentTarget
1810 problem
@?
= expected targetSelector
1813 "expected resolveTargets result: (Left [problem]) "
1817 testExceptionInFindingPackage
:: ProjectConfig
-> Assertion
1818 testExceptionInFindingPackage config
= do
1819 BadPackageLocations _ locs
<-
1820 expectException
"BadPackageLocations" $
1822 planProject testdir config
1824 [BadLocGlobEmptyMatch
"./*.cabal"] -> return ()
1825 _
-> assertFailure
"expected BadLocGlobEmptyMatch"
1826 cleanProject testdir
1828 testdir
= "exception/no-pkg"
1830 testExceptionInFindingPackage2
:: ProjectConfig
-> Assertion
1831 testExceptionInFindingPackage2 config
= do
1832 BadPackageLocations _ locs
<-
1833 expectException
"BadPackageLocations" $
1835 planProject testdir config
1837 [BadPackageLocationFile
(BadLocDirNoCabalFile
".")] -> return ()
1838 _
-> assertFailure
$ "expected BadLocDirNoCabalFile, got " ++ show locs
1839 cleanProject testdir
1841 testdir
= "exception/no-pkg2"
1843 testExceptionInProjectConfig
:: ProjectConfig
-> Assertion
1844 testExceptionInProjectConfig config
= do
1845 BadPerPackageCompilerPaths ps
<-
1846 expectException
"BadPerPackageCompilerPaths" $
1848 planProject testdir config
1850 [(pn
, "ghc")] |
"foo" == pn
-> return ()
1853 "expected (PackageName \"foo\",\"ghc\"), got "
1855 cleanProject testdir
1857 testdir
= "exception/bad-config"
1859 testExceptionInConfigureStep
:: ProjectConfig
-> Assertion
1860 testExceptionInConfigureStep config
= do
1861 (plan
, res
) <- executePlan
=<< planProject testdir config
1862 (_pkga1
, failure
) <- expectPackageFailed plan res pkgidA1
1863 case buildFailureReason failure
of
1864 ConfigureFailed _
-> return ()
1865 _
-> assertFailure
$ "expected ConfigureFailed, got " ++ show failure
1866 cleanProject testdir
1868 testdir
= "exception/configure"
1869 pkgidA1
= PackageIdentifier
"a" (mkVersion
[1])
1871 testExceptionInBuildStep
:: ProjectConfig
-> Assertion
1872 testExceptionInBuildStep config
= do
1873 (plan
, res
) <- executePlan
=<< planProject testdir config
1874 (_pkga1
, failure
) <- expectPackageFailed plan res pkgidA1
1875 expectBuildFailed failure
1877 testdir
= "exception/build"
1878 pkgidA1
= PackageIdentifier
"a" (mkVersion
[1])
1880 testSetupScriptStyles
:: ProjectConfig
-> (String -> IO ()) -> Assertion
1881 testSetupScriptStyles config reportSubCase
= do
1882 reportSubCase
(show SetupCustomExplicitDeps
)
1884 plan0
@(_
, _
, sharedConfig
) <- planProject testdir1 config
1886 let isOSX
(Platform _ OSX
) = True
1888 compilerVer
= compilerVersion
(pkgConfigCompiler sharedConfig
)
1889 -- Skip the Custom tests when the shipped Cabal library is buggy
1891 ( (isOSX
(pkgConfigPlatform sharedConfig
) && (compilerVer
< mkVersion
[7, 10]))
1892 -- 9.10 ships Cabal 3.12.0.0 affected by #9940
1893 ||
(mkVersion
[9, 10] <= compilerVer
&& compilerVer
< mkVersion
[9, 11])
1896 (plan1
, res1
) <- executePlan plan0
1897 pkg1
<- expectPackageInstalled plan1 res1 pkgidA
1898 elabSetupScriptStyle pkg1
@?
= SetupCustomExplicitDeps
1899 hasDefaultSetupDeps pkg1
@?
= Just
False
1900 marker1
<- readFile (basedir
</> testdir1
</> "marker")
1902 removeFile (basedir
</> testdir1
</> "marker")
1904 -- implicit deps implies 'Cabal < 2' which conflicts w/ GHC 8.2 or later
1905 when (compilerVersion
(pkgConfigCompiler sharedConfig
) < mkVersion
[8, 2]) $ do
1906 reportSubCase
(show SetupCustomImplicitDeps
)
1907 (plan2
, res2
) <- executePlan
=<< planProject testdir2 config
1908 pkg2
<- expectPackageInstalled plan2 res2 pkgidA
1909 elabSetupScriptStyle pkg2
@?
= SetupCustomImplicitDeps
1910 hasDefaultSetupDeps pkg2
@?
= Just
True
1911 marker2
<- readFile (basedir
</> testdir2
</> "marker")
1913 removeFile (basedir
</> testdir2
</> "marker")
1915 reportSubCase
(show SetupNonCustomInternalLib
)
1916 (plan3
, res3
) <- executePlan
=<< planProject testdir3 config
1917 pkg3
<- expectPackageInstalled plan3 res3 pkgidA
1918 elabSetupScriptStyle pkg3
@?
= SetupNonCustomInternalLib
1921 --TODO: the SetupNonCustomExternalLib case is hard to test since it
1922 -- requires a version of Cabal that's later than the one we're testing
1923 -- e.g. needs a .cabal file that specifies cabal-version: >= 2.0
1924 -- and a corresponding Cabal package that we can use to try and build a
1925 -- default Setup.hs.
1926 reportSubCase (show SetupNonCustomExternalLib)
1927 (plan4, res4) <- executePlan =<< planProject testdir4 config
1928 pkg4 <- expectPackageInstalled plan4 res4 pkgidA
1929 pkgSetupScriptStyle pkg4 @?= SetupNonCustomExternalLib
1932 testdir1
= "build/setup-custom1"
1933 testdir2
= "build/setup-custom2"
1934 testdir3
= "build/setup-simple"
1935 pkgidA
= PackageIdentifier
"a" (mkVersion
[0, 1])
1936 -- The solver fills in default setup deps explicitly, but marks them as such
1937 hasDefaultSetupDeps
=
1938 fmap defaultSetupDepends
1940 . elabPkgDescription
1942 -- | Test the behaviour with and without @--keep-going@
1943 testBuildKeepGoing
:: ProjectConfig
-> Assertion
1944 testBuildKeepGoing config
= do
1945 -- P is expected to fail, Q does not depend on P but without
1946 -- parallel build and without keep-going then we don't build Q yet.
1947 (plan1
, res1
) <- executePlan
=<< planProject testdir
(config `mappend` keepGoing
False)
1948 (_
, failure1
) <- expectPackageFailed plan1 res1
"p-0.1"
1949 expectBuildFailed failure1
1950 _
<- expectPackageConfigured plan1 res1
"q-0.1"
1952 -- With keep-going then we should go on to successfully build Q
1955 =<< planProject testdir
(config `mappend` keepGoing
True)
1956 (_
, failure2
) <- expectPackageFailed plan2 res2
"p-0.1"
1957 expectBuildFailed failure2
1958 _
<- expectPackageInstalled plan2 res2
"q-0.1"
1961 testdir
= "build/keep-going"
1964 { projectConfigBuildOnly
=
1966 { projectConfigKeepGoing
= toFlag kg
1970 -- | Test we can successfully build packages from local tarball files.
1971 testBuildLocalTarball
:: ProjectConfig
-> Assertion
1972 testBuildLocalTarball config
= do
1973 -- P is a tarball package, Q is a local dir package that depends on it.
1974 (plan
, res
) <- executePlan
=<< planProject testdir config
1975 _
<- expectPackageInstalled plan res
"p-0.1"
1976 _
<- expectPackageInstalled plan res
"q-0.1"
1979 testdir
= "build/local-tarball"
1981 -- | See <https://github.com/haskell/cabal/issues/3324>
1983 -- This test just doesn't seem to work on Windows,
1984 -- due filesystem woes.
1985 testRegressionIssue3324
:: ProjectConfig
-> Assertion
1986 testRegressionIssue3324 config
= when (buildOS
/= Windows
) $ do
1987 -- expected failure first time due to missing dep
1988 (plan1
, res1
) <- executePlan
=<< planProject testdir config
1989 (_pkgq
, failure
) <- expectPackageFailed plan1 res1
"q-0.1"
1990 expectBuildFailed failure
1992 -- add the missing dep, now it should work
1993 let qcabal
= basedir
</> testdir
</> "q" </> "q.cabal"
1994 withFileFinallyRestore qcabal
$ do
1995 tryFewTimes
$ BS
.appendFile qcabal
(" build-depends: p\n")
1996 (plan2
, res2
) <- executePlan
=<< planProject testdir config
1997 _
<- expectPackageInstalled plan2 res2
"p-0.1"
1998 _
<- expectPackageInstalled plan2 res2
"q-0.1"
2001 testdir
= "regression/3324"
2003 -- | Test global program options are propagated correctly
2004 -- from ProjectConfig to ElaboratedInstallPlan
2005 testProgramOptionsAll
:: ProjectConfig
-> Assertion
2006 testProgramOptionsAll config0
= do
2007 -- P is a tarball package, Q is a local dir package that depends on it.
2008 (_
, elaboratedPlan
, _
) <- planProject testdir config
2009 let packages
= filterConfiguredPackages
$ InstallPlan
.toList elaboratedPlan
2014 (getProgArgs packages
"q")
2018 (getProgArgs packages
"p")
2020 testdir
= "regression/program-options"
2021 programArgs
= MapMappend
(Map
.fromList
[("ghc", [ghcFlag
])])
2022 ghcFlag
= "-fno-full-laziness"
2024 -- Insert flag into global config
2027 { projectConfigAllPackages
=
2028 (projectConfigAllPackages config0
)
2029 { packageConfigProgramArgs
= programArgs
2033 -- | Test local program options are propagated correctly
2034 -- from ProjectConfig to ElaboratedInstallPlan
2035 testProgramOptionsLocal
:: ProjectConfig
-> Assertion
2036 testProgramOptionsLocal config0
= do
2037 (_
, elaboratedPlan
, _
) <- planProject testdir config
2038 let localPackages
= filterConfiguredPackages
$ InstallPlan
.toList elaboratedPlan
2043 (getProgArgs localPackages
"q")
2047 (getProgArgs localPackages
"p")
2049 testdir
= "regression/program-options"
2050 programArgs
= MapMappend
(Map
.fromList
[("ghc", [ghcFlag
])])
2051 ghcFlag
= "-fno-full-laziness"
2053 -- Insert flag into local config
2056 { projectConfigLocalPackages
=
2057 (projectConfigLocalPackages config0
)
2058 { packageConfigProgramArgs
= programArgs
2062 -- | Test package specific program options are propagated correctly
2063 -- from ProjectConfig to ElaboratedInstallPlan
2064 testProgramOptionsSpecific
:: ProjectConfig
-> Assertion
2065 testProgramOptionsSpecific config0
= do
2066 (_
, elaboratedPlan
, _
) <- planProject testdir config
2067 let packages
= filterConfiguredPackages
$ InstallPlan
.toList elaboratedPlan
2072 (getProgArgs packages
"q")
2076 (getProgArgs packages
"p")
2078 testdir
= "regression/program-options"
2079 programArgs
= MapMappend
(Map
.fromList
[("ghc", [ghcFlag
])])
2080 ghcFlag
= "-fno-full-laziness"
2082 -- Insert flag into package "p" config
2085 { projectConfigSpecificPackage
= MapMappend
(Map
.fromList
[(mkPackageName
"p", configArgs
)])
2089 { packageConfigProgramArgs
= programArgs
2092 filterConfiguredPackages
:: [ElaboratedPlanPackage
] -> [ElaboratedConfiguredPackage
]
2093 filterConfiguredPackages
[] = []
2094 filterConfiguredPackages
(InstallPlan
.PreExisting _
: pkgs
) = filterConfiguredPackages pkgs
2095 filterConfiguredPackages
(InstallPlan
.Installed elab
: pkgs
) = elab
: filterConfiguredPackages pkgs
2096 filterConfiguredPackages
(InstallPlan
.Configured elab
: pkgs
) = elab
: filterConfiguredPackages pkgs
2098 getProgArgs
:: [ElaboratedConfiguredPackage
] -> String -> Maybe [String]
2099 getProgArgs
[] _
= Nothing
2100 getProgArgs
(elab
: pkgs
) name
2101 | pkgName
(elabPkgSourceId elab
) == mkPackageName name
=
2102 Map
.lookup "ghc" (elabProgramArgs elab
)
2104 getProgArgs pkgs name
2106 ---------------------------------
2107 -- Test utils to plan and build
2111 basedir
= "tests" </> "IntegrationTests2"
2113 dirActions
:: FilePath -> TS
.DirActions
IO
2114 dirActions testdir
=
2116 { TS
.doesFileExist = \p
->
2117 TS
.doesFileExist defaultDirActions
(virtcwd
</> p
)
2118 , TS
.doesDirectoryExist = \p
->
2119 TS
.doesDirectoryExist defaultDirActions
(virtcwd
</> p
)
2120 , TS
.canonicalizePath
= \p
->
2121 TS
.canonicalizePath defaultDirActions
(virtcwd
</> p
)
2122 , TS
.getCurrentDirectory =
2123 TS
.canonicalizePath defaultDirActions virtcwd
2126 virtcwd
= basedir
</> testdir
2132 , [PackageSpecifier UnresolvedSourcePackage
]
2136 configureProject
:: FilePath -> ProjectConfig
-> IO ProjDetails
2137 configureProject testdir cliConfig
= do
2138 cabalDirLayout
<- defaultCabalDirLayout
2140 projectRootDir
<- canonicalizePath
(basedir
</> testdir
)
2141 isexplict
<- doesFileExist (projectRootDir
</> defaultProjectFile
)
2144 | isexplict
= ProjectRootExplicit projectRootDir defaultProjectFile
2145 |
otherwise = ProjectRootImplicit projectRootDir
2146 distDirLayout
= defaultDistDirLayout projectRoot Nothing Nothing
2148 -- Clear state between test runs. The state remains if the previous run
2149 -- ended in an exception (as we leave the files to help with debugging).
2150 cleanProject testdir
2152 httpTransport
<- configureTransport verbosity
[] Nothing
2154 (projectConfig
, localPackages
) <-
2155 rebuildProjectConfig
2162 resolveBuildTimeSettings
2177 , ElaboratedInstallPlan
2178 , ElaboratedSharedConfig
2181 planProject
:: FilePath -> ProjectConfig
-> IO PlanDetails
2182 planProject testdir cliConfig
= do
2183 projDetails
@( distDirLayout
2189 configureProject testdir cliConfig
2191 (elaboratedPlan
, _
, elaboratedShared
, _
, _
) <-
2206 executePlan
:: PlanDetails
-> IO (ElaboratedInstallPlan
, BuildOutcomes
)
2208 ( (distDirLayout
, cabalDirLayout
, config
, _
, buildSettings
)
2212 let targets
:: Map
.Map UnitId
[ComponentTarget
]
2215 [ (unitid
, [ComponentTarget cname WholeComponent
])
2216 | ts
<- Map
.elems (availableTargets elaboratedPlan
)
2218 { availableTargetStatus
= TargetBuildable
(unitid
, cname
) _
2223 pruneInstallPlanToTargets
2229 rebuildTargetsDryRun
2234 let elaboratedPlan
'' =
2235 improveInstallPlanWithUpToDatePackages
2244 (cabalStoreDirLayout cabalDirLayout
)
2248 -- Avoid trying to use act-as-setup mode:
2249 buildSettings
{buildSettingNumJobs
= Serial
}
2251 return (elaboratedPlan
'', buildOutcomes
)
2253 cleanProject
:: FilePath -> IO ()
2254 cleanProject testdir
= do
2255 alreadyExists
<- doesDirectoryExist distDir
2256 when alreadyExists
$ removePathForcibly distDir
2258 projectRoot
= ProjectRootImplicit
(basedir
</> testdir
)
2259 distDirLayout
= defaultDistDirLayout projectRoot Nothing Nothing
2260 distDir
= distDirectory distDirLayout
2262 verbosity
:: Verbosity
2263 verbosity
= minBound -- normal --verbose --maxBound --minBound
2265 -------------------------------------------
2266 -- Tasty integration to adjust the config
2269 withProjectConfig
:: (ProjectConfig
-> TestTree
) -> TestTree
2270 withProjectConfig testtree
=
2271 askOption
$ \ghcPath
->
2272 testtree
(mkProjectConfig ghcPath
)
2274 mkProjectConfig
:: GhcPath
-> ProjectConfig
2275 mkProjectConfig
(GhcPath ghcPath
) =
2277 { projectConfigShared
=
2279 { projectConfigHcPath
= maybeToFlag ghcPath
2281 , projectConfigBuildOnly
=
2283 { projectConfigNumJobs
= toFlag
(Just
1)
2287 maybeToFlag
= maybe mempty toFlag
2289 data GhcPath
= GhcPath
(Maybe FilePath)
2292 instance IsOption GhcPath
where
2293 defaultValue
= GhcPath Nothing
2294 optionName
= Tagged
"with-ghc"
2295 optionHelp
= Tagged
"The ghc compiler to use"
2296 parseValue
= Just
. GhcPath
. Just
2298 projectConfigOptionDescriptions
:: [OptionDescription
]
2299 projectConfigOptionDescriptions
= [Option
(Proxy
:: Proxy GhcPath
)]
2301 ---------------------------------------
2302 -- HUint style utils for this context
2305 expectException
:: Exception e
=> String -> IO a
-> IO e
2306 expectException expected action
= do
2310 Right _
-> throwIO
$ HUnitFailure Nothing
$ "expected an exception " ++ expected
2312 expectPackagePreExisting
2313 :: ElaboratedInstallPlan
2316 -> IO InstalledPackageInfo
2317 expectPackagePreExisting plan buildOutcomes pkgid
= do
2318 planpkg
<- expectPlanPackage plan pkgid
2319 case (planpkg
, InstallPlan
.lookupBuildOutcome planpkg buildOutcomes
) of
2320 (InstallPlan
.PreExisting pkg
, Nothing
) ->
2322 (_
, buildResult
) -> unexpectedBuildResult
"PreExisting" planpkg buildResult
2324 expectPackageConfigured
2325 :: ElaboratedInstallPlan
2328 -> IO ElaboratedConfiguredPackage
2329 expectPackageConfigured plan buildOutcomes pkgid
= do
2330 planpkg
<- expectPlanPackage plan pkgid
2331 case (planpkg
, InstallPlan
.lookupBuildOutcome planpkg buildOutcomes
) of
2332 (InstallPlan
.Configured pkg
, Nothing
) ->
2334 (_
, buildResult
) -> unexpectedBuildResult
"Configured" planpkg buildResult
2336 expectPackageInstalled
2337 :: ElaboratedInstallPlan
2340 -> IO ElaboratedConfiguredPackage
2341 expectPackageInstalled plan buildOutcomes pkgid
= do
2342 planpkg
<- expectPlanPackage plan pkgid
2343 case (planpkg
, InstallPlan
.lookupBuildOutcome planpkg buildOutcomes
) of
2344 (InstallPlan
.Configured pkg
, Just
(Right _result
)) ->
2345 -- result isn't used by any test
2347 -- package can be installed in the global .store!
2348 -- (when installing from tarball!)
2349 (InstallPlan
.Installed pkg
, Nothing
) ->
2351 (_
, buildResult
) -> unexpectedBuildResult
"Installed" planpkg buildResult
2354 :: ElaboratedInstallPlan
2357 -> IO (ElaboratedConfiguredPackage
, BuildFailure
)
2358 expectPackageFailed plan buildOutcomes pkgid
= do
2359 planpkg
<- expectPlanPackage plan pkgid
2360 case (planpkg
, InstallPlan
.lookupBuildOutcome planpkg buildOutcomes
) of
2361 (InstallPlan
.Configured pkg
, Just
(Left failure
)) ->
2362 return (pkg
, failure
)
2363 (_
, buildResult
) -> unexpectedBuildResult
"Failed" planpkg buildResult
2365 unexpectedBuildResult
2367 -> ElaboratedPlanPackage
2368 -> Maybe (Either BuildFailure BuildResult
)
2370 unexpectedBuildResult expected planpkg buildResult
=
2372 HUnitFailure Nothing
$
2374 ++ display
(packageId planpkg
)
2377 ++ " state, but it is actually in the "
2381 actual
= case (buildResult
, planpkg
) of
2382 (Nothing
, InstallPlan
.PreExisting
{}) -> "PreExisting"
2383 (Nothing
, InstallPlan
.Configured
{}) -> "Configured"
2384 (Just
(Right _
), InstallPlan
.Configured
{}) -> "Installed"
2385 (Just
(Left _
), InstallPlan
.Configured
{}) -> "Failed"
2386 (Nothing
, InstallPlan
.Installed
{}) -> "Installed globally"
2387 _
-> "Impossible! " ++ show buildResult
++ show planpkg
2390 :: ElaboratedInstallPlan
2392 -> IO ElaboratedPlanPackage
2393 expectPlanPackage plan pkgid
=
2395 | pkg
<- InstallPlan
.toList plan
2396 , packageId pkg
== pkgid
2401 HUnitFailure Nothing
$
2404 ++ " in the install plan but it's not there"
2407 HUnitFailure Nothing
$
2408 "expected to find only one instance of "
2410 ++ " in the install plan but there's several"
2412 expectBuildFailed
:: BuildFailure
-> IO ()
2413 expectBuildFailed
(BuildFailure _
(BuildFailed _
)) = return ()
2414 expectBuildFailed
(BuildFailure _ reason
) =
2415 assertFailure
$ "expected BuildFailed, got " ++ show reason
2417 ---------------------------------------
2421 -- | Allow altering a file during a test, but then restore it afterwards
2423 -- We read into the memory, as filesystems are tricky. (especially Windows)
2424 withFileFinallyRestore
:: FilePath -> IO a
-> IO a
2425 withFileFinallyRestore file action
= do
2426 originalContents
<- BS
.readFile file
2427 action `finally` handle onIOError
(tryFewTimes
$ BS
.writeFile file originalContents
)
2429 onIOError
:: IOException
-> IO ()
2430 onIOError e
= putStrLn $ "WARNING: Cannot restore " ++ file
++ "; " ++ show e
2432 -- Hopefully works around some Windows file-locking things.
2435 -- Try action 4 times, with small sleep in between,
2436 -- retrying if it fails for 'IOException' reason.
2438 tryFewTimes
:: forall a
. IO a
-> IO a
2439 tryFewTimes action
= go
(3 :: Int)
2444 |
otherwise = action `
catch` onIOError n
2446 onIOError
:: Int -> IOException
-> IO a
2448 hPutStrLn stderr $ "Trying " ++ show n
++ " after " ++ show e
2452 testNixFlags
:: Assertion
2454 let gc
= globalCommand
[]
2455 -- changing from the v1 to v2 build command does not change whether the "--enable-nix" flag
2456 -- sets the globalNix param of the GlobalFlags type to True even though the v2 command doesn't use it
2457 let nixEnabledFlags
= getFlags gc
. commandParseArgs gc
True $ ["--enable-nix", "build"]
2458 let nixDisabledFlags
= getFlags gc
. commandParseArgs gc
True $ ["--disable-nix", "build"]
2459 let nixDefaultFlags
= getFlags gc
. commandParseArgs gc
True $ ["build"]
2460 True @=?
isJust nixDefaultFlags
2461 True @=?
isJust nixEnabledFlags
2462 True @=?
isJust nixDisabledFlags
2463 Just
True @=?
(fromFlag
. globalNix
. fromJust $ nixEnabledFlags
)
2464 Just
False @=?
(fromFlag
. globalNix
. fromJust $ nixDisabledFlags
)
2465 Nothing
@=?
(fromFlag
. globalNix
. fromJust $ nixDefaultFlags
)
2467 -- Config file options
2468 trueConfig
<- loadConfig verbosity
(Flag
(basedir
</> "nix-config/nix-true"))
2469 falseConfig
<- loadConfig verbosity
(Flag
(basedir
</> "nix-config/nix-false"))
2471 Just
True @=?
(fromFlag
. globalNix
. savedGlobalFlags
$ trueConfig
)
2472 Just
False @=?
(fromFlag
. globalNix
. savedGlobalFlags
$ falseConfig
)
2474 fromFlag
:: Flag
Bool -> Maybe Bool
2475 fromFlag
(Flag x
) = Just x
2476 fromFlag NoFlag
= Nothing
2477 getFlags
:: CommandUI GlobalFlags
-> CommandParse
(GlobalFlags
-> GlobalFlags
, [String]) -> Maybe GlobalFlags
2478 getFlags cui
(CommandReadyToGo
(mkflags
, _
)) = Just
. mkflags
. commandDefaultFlags
$ cui
2479 getFlags _ _
= Nothing
2481 -- Tests whether config options are commented or not
2482 testConfigOptionComments
:: Assertion
2483 testConfigOptionComments
= do
2485 -- \| Find the first line containing a target setting name.
2487 -- If `isComment` is set, only comment lines will be found.
2488 findLineWith
:: Bool -> String -> String -> String
2489 findLineWith isComment target text
=
2490 case findLinesWith isComment target text
of
2492 (l
: _
) -> removeColonAndAfter l
2494 -- \| Find lines containing a target setting name.
2495 findLinesWith
:: Bool -> String -> String -> [String]
2496 findLinesWith isComment target
2497 | isComment
= filter (isInfixOf
("-- " ++ target
++ ":")) . lines
2498 |
otherwise = filter (isInfixOf
(target
++ ":")) . lines
2500 -- \| Transform @-- puppy: doggy@ into @-- puppy@.
2501 removeColonAndAfter
:: String -> String
2502 removeColonAndAfter
= takeWhile (/= ':')
2504 cwd
<- getCurrentDirectory
2505 let configFile
= cwd
</> basedir
</> "config" </> "default-config"
2506 _
<- createDefaultConfigFile verbosity
[] configFile
2507 defaultConfigFile
<- readFile configFile
2510 -- TODO: These assertions are fairly weak. Potential improvements:
2512 -- - Include the section name in the assertion, so that (e.g.) a
2513 -- `keep-temp-files` setting in the `haddock` section won't be confused
2514 -- with a `keep-temp-files` setting in the `init` section.
2516 -- - Check all matching lines to confirm that settings are not listed
2517 -- multiple times. For example, `cabal-file` is listed twice right now,
2518 -- once under the `haddock` settings!
2520 -- - Consume the file as we go, ensuring that the settings are in a given
2523 -- - Check the generated config file into Git (replacing e.g. `$HOME` with
2524 -- a sentinel value) so changes show up in PR diffs.
2525 assertHasLine
' :: Bool -> String -> String -> Assertion
2526 assertHasLine
' isComment expected settingName
=
2527 let actual
= findLineWith isComment settingName defaultConfigFile
2529 "Did not find expected line for setting "
2531 <> " in configuration file "
2533 in assertEqual messagePrefix expected actual
2535 assertHasLine
:: String -> String -> Assertion
2536 assertHasLine
= assertHasLine
' False
2538 assertHasCommentLine
:: String -> String -> Assertion
2539 assertHasCommentLine
= assertHasLine
' True
2541 " url" `assertHasLine`
"url"
2542 " -- secure" `assertHasCommentLine`
"secure"
2543 " -- root-keys" `assertHasCommentLine`
"root-keys"
2544 " -- key-threshold" `assertHasCommentLine`
"key-threshold"
2546 "-- ignore-expiry" `assertHasCommentLine`
"ignore-expiry"
2547 "-- http-transport" `assertHasCommentLine`
"http-transport"
2548 "-- nix" `assertHasCommentLine`
"nix"
2549 "-- store-dir" `assertHasCommentLine`
"store-dir"
2550 "-- active-repositories" `assertHasCommentLine`
"active-repositories"
2551 "-- local-no-index-repo" `assertHasCommentLine`
"local-no-index-repo"
2552 "remote-repo-cache" `assertHasLine`
"remote-repo-cache"
2553 "-- logs-dir" `assertHasCommentLine`
"logs-dir"
2554 "-- default-user-config" `assertHasCommentLine`
"default-user-config"
2555 "-- verbose" `assertHasCommentLine`
"verbose"
2556 "-- compiler" `assertHasCommentLine`
"compiler"
2557 "-- cabal-file" `assertHasCommentLine`
"cabal-file"
2558 "-- keep-temp-files" `assertHasCommentLine`
"keep-temp-files"
2559 "-- with-compiler" `assertHasCommentLine`
"with-compiler"
2560 "-- with-hc-pkg" `assertHasCommentLine`
"with-hc-pkg"
2561 "-- program-prefix" `assertHasCommentLine`
"program-prefix"
2562 "-- program-suffix" `assertHasCommentLine`
"program-suffix"
2563 "-- library-vanilla" `assertHasCommentLine`
"library-vanilla"
2564 "-- library-profiling" `assertHasCommentLine`
"library-profiling"
2565 "-- shared" `assertHasCommentLine`
"shared"
2566 "-- static" `assertHasCommentLine`
"static"
2567 "-- executable-dynamic" `assertHasCommentLine`
"executable-dynamic"
2568 "-- executable-static" `assertHasCommentLine`
"executable-static"
2569 "-- profiling" `assertHasCommentLine`
"profiling"
2570 "-- executable-profiling" `assertHasCommentLine`
"executable-profiling"
2571 "-- profiling-detail" `assertHasCommentLine`
"profiling-detail"
2572 "-- library-profiling-detail" `assertHasCommentLine`
"library-profiling-detail"
2573 "-- optimization" `assertHasCommentLine`
"optimization"
2574 "-- debug-info" `assertHasCommentLine`
"debug-info"
2575 "-- build-info" `assertHasCommentLine`
"build-info"
2576 "-- library-for-ghci" `assertHasCommentLine`
"library-for-ghci"
2577 "-- split-sections" `assertHasCommentLine`
"split-sections"
2578 "-- split-objs" `assertHasCommentLine`
"split-objs"
2579 "-- executable-stripping" `assertHasCommentLine`
"executable-stripping"
2580 "-- library-stripping" `assertHasCommentLine`
"library-stripping"
2581 "-- configure-option" `assertHasCommentLine`
"configure-option"
2582 "-- user-install" `assertHasCommentLine`
"user-install"
2583 "-- package-db" `assertHasCommentLine`
"package-db"
2584 "-- flags" `assertHasCommentLine`
"flags"
2585 "-- extra-include-dirs" `assertHasCommentLine`
"extra-include-dirs"
2586 "-- deterministic" `assertHasCommentLine`
"deterministic"
2587 "-- cid" `assertHasCommentLine`
"cid"
2588 "-- extra-lib-dirs" `assertHasCommentLine`
"extra-lib-dirs"
2589 "-- extra-lib-dirs-static" `assertHasCommentLine`
"extra-lib-dirs-static"
2590 "-- extra-framework-dirs" `assertHasCommentLine`
"extra-framework-dirs"
2591 "-- extra-prog-path" `assertHasLine`
"extra-prog-path"
2592 "-- instantiate-with" `assertHasCommentLine`
"instantiate-with"
2593 "-- tests" `assertHasCommentLine`
"tests"
2594 "-- coverage" `assertHasCommentLine`
"coverage"
2595 "-- library-coverage" `assertHasCommentLine`
"library-coverage"
2596 "-- exact-configuration" `assertHasCommentLine`
"exact-configuration"
2597 "-- benchmarks" `assertHasCommentLine`
"benchmarks"
2598 "-- relocatable" `assertHasCommentLine`
"relocatable"
2599 "-- response-files" `assertHasCommentLine`
"response-files"
2600 "-- allow-depending-on-private-libs" `assertHasCommentLine`
"allow-depending-on-private-libs"
2601 "-- cabal-lib-version" `assertHasCommentLine`
"cabal-lib-version"
2602 "-- append" `assertHasCommentLine`
"append"
2603 "-- backup" `assertHasCommentLine`
"backup"
2604 "-- constraint" `assertHasCommentLine`
"constraint"
2605 "-- preference" `assertHasCommentLine`
"preference"
2606 "-- solver" `assertHasCommentLine`
"solver"
2607 "-- allow-older" `assertHasCommentLine`
"allow-older"
2608 "-- allow-newer" `assertHasCommentLine`
"allow-newer"
2609 "-- write-ghc-environment-files" `assertHasCommentLine`
"write-ghc-environment-files"
2610 "-- documentation" `assertHasCommentLine`
"documentation"
2611 "-- doc-index-file" `assertHasCommentLine`
"doc-index-file"
2612 "-- only-download" `assertHasCommentLine`
"only-download"
2613 "-- target-package-db" `assertHasCommentLine`
"target-package-db"
2614 "-- max-backjumps" `assertHasCommentLine`
"max-backjumps"
2615 "-- reorder-goals" `assertHasCommentLine`
"reorder-goals"
2616 "-- count-conflicts" `assertHasCommentLine`
"count-conflicts"
2617 "-- fine-grained-conflicts" `assertHasCommentLine`
"fine-grained-conflicts"
2618 "-- minimize-conflict-set" `assertHasCommentLine`
"minimize-conflict-set"
2619 "-- independent-goals" `assertHasCommentLine`
"independent-goals"
2620 "-- prefer-oldest" `assertHasCommentLine`
"prefer-oldest"
2621 "-- shadow-installed-packages" `assertHasCommentLine`
"shadow-installed-packages"
2622 "-- strong-flags" `assertHasCommentLine`
"strong-flags"
2623 "-- allow-boot-library-installs" `assertHasCommentLine`
"allow-boot-library-installs"
2624 "-- reject-unconstrained-dependencies" `assertHasCommentLine`
"reject-unconstrained-dependencies"
2625 "-- reinstall" `assertHasCommentLine`
"reinstall"
2626 "-- avoid-reinstalls" `assertHasCommentLine`
"avoid-reinstalls"
2627 "-- force-reinstalls" `assertHasCommentLine`
"force-reinstalls"
2628 "-- upgrade-dependencies" `assertHasCommentLine`
"upgrade-dependencies"
2629 "-- index-state" `assertHasCommentLine`
"index-state"
2630 "-- root-cmd" `assertHasCommentLine`
"root-cmd"
2631 "-- symlink-bindir" `assertHasCommentLine`
"symlink-bindir"
2632 "build-summary" `assertHasLine`
"build-summary"
2633 "-- build-log" `assertHasCommentLine`
"build-log"
2634 "remote-build-reporting" `assertHasLine`
"remote-build-reporting"
2635 "-- report-planning-failure" `assertHasCommentLine`
"report-planning-failure"
2636 "-- per-component" `assertHasCommentLine`
"per-component"
2637 "-- run-tests" `assertHasCommentLine`
"run-tests"
2638 "jobs" `assertHasLine`
"jobs"
2639 "-- keep-going" `assertHasCommentLine`
"keep-going"
2640 "-- offline" `assertHasCommentLine`
"offline"
2641 "-- lib" `assertHasCommentLine`
"lib"
2642 "-- package-env" `assertHasCommentLine`
"package-env"
2643 "-- overwrite-policy" `assertHasCommentLine`
"overwrite-policy"
2644 "-- install-method" `assertHasCommentLine`
"install-method"
2645 "installdir" `assertHasLine`
"installdir"
2646 "-- token" `assertHasCommentLine`
"token"
2647 "-- username" `assertHasCommentLine`
"username"
2648 "-- password" `assertHasCommentLine`
"password"
2649 "-- password-command" `assertHasCommentLine`
"password-command"
2650 "-- builddir" `assertHasCommentLine`
"builddir"
2652 " -- hoogle" `assertHasCommentLine`
"hoogle"
2653 " -- html" `assertHasCommentLine`
"html"
2654 " -- html-location" `assertHasCommentLine`
"html-location"
2655 " -- executables" `assertHasCommentLine`
"executables"
2656 " -- foreign-libraries" `assertHasCommentLine`
"foreign-libraries"
2657 " -- all" `assertHasCommentLine`
"all"
2658 " -- internal" `assertHasCommentLine`
"internal"
2659 " -- css" `assertHasCommentLine`
"css"
2660 " -- hyperlink-source" `assertHasCommentLine`
"hyperlink-source"
2661 " -- quickjump" `assertHasCommentLine`
"quickjump"
2662 " -- hscolour-css" `assertHasCommentLine`
"hscolour-css"
2663 " -- contents-location" `assertHasCommentLine`
"contents-location"
2664 " -- index-location" `assertHasCommentLine`
"index-location"
2665 " -- base-url" `assertHasCommentLine`
"base-url"
2666 " -- resources-dir" `assertHasCommentLine`
"resources-dir"
2667 " -- output-dir" `assertHasCommentLine`
"output-dir"
2668 " -- use-unicode" `assertHasCommentLine`
"use-unicode"
2670 " -- interactive" `assertHasCommentLine`
"interactive"
2671 " -- quiet" `assertHasCommentLine`
"quiet"
2672 " -- no-comments" `assertHasCommentLine`
"no-comments"
2673 " -- minimal" `assertHasCommentLine`
"minimal"
2674 " -- cabal-version" `assertHasCommentLine`
"cabal-version"
2675 " -- license" `assertHasCommentLine`
"license"
2676 " -- extra-doc-file" `assertHasCommentLine`
"extra-doc-file"
2677 " -- test-dir" `assertHasCommentLine`
"test-dir"
2678 " -- simple" `assertHasCommentLine`
"simple"
2679 " -- language" `assertHasCommentLine`
"language"
2680 " -- application-dir" `assertHasCommentLine`
"application-dir"
2681 " -- source-dir" `assertHasCommentLine`
"source-dir"
2683 " -- prefix" `assertHasCommentLine`
"prefix"
2684 " -- bindir" `assertHasCommentLine`
"bindir"
2685 " -- libdir" `assertHasCommentLine`
"libdir"
2686 " -- libsubdir" `assertHasCommentLine`
"libsubdir"
2687 " -- dynlibdir" `assertHasCommentLine`
"dynlibdir"
2688 " -- libexecdir" `assertHasCommentLine`
"libexecdir"
2689 " -- libexecsubdir" `assertHasCommentLine`
"libexecsubdir"
2690 " -- datadir" `assertHasCommentLine`
"datadir"
2691 " -- datasubdir" `assertHasCommentLine`
"datasubdir"
2692 " -- docdir" `assertHasCommentLine`
"docdir"
2693 " -- htmldir" `assertHasCommentLine`
"htmldir"
2694 " -- haddockdir" `assertHasCommentLine`
"haddockdir"
2695 " -- sysconfdir" `assertHasCommentLine`
"sysconfdir"
2697 " -- alex-location" `assertHasCommentLine`
"alex-location"
2698 " -- ar-location" `assertHasCommentLine`
"ar-location"
2699 " -- c2hs-location" `assertHasCommentLine`
"c2hs-location"
2700 " -- cpphs-location" `assertHasCommentLine`
"cpphs-location"
2701 " -- doctest-location" `assertHasCommentLine`
"doctest-location"
2702 " -- gcc-location" `assertHasCommentLine`
"gcc-location"
2703 " -- ghc-location" `assertHasCommentLine`
"ghc-location"
2704 " -- ghc-pkg-location" `assertHasCommentLine`
"ghc-pkg-location"
2705 " -- ghcjs-location" `assertHasCommentLine`
"ghcjs-location"
2706 " -- ghcjs-pkg-location" `assertHasCommentLine`
"ghcjs-pkg-location"
2707 " -- greencard-location" `assertHasCommentLine`
"greencard-location"
2708 " -- haddock-location" `assertHasCommentLine`
"haddock-location"
2709 " -- happy-location" `assertHasCommentLine`
"happy-location"
2710 " -- haskell-suite-location" `assertHasCommentLine`
"haskell-suite-location"
2711 " -- haskell-suite-pkg-location" `assertHasCommentLine`
"haskell-suite-pkg-location"
2712 " -- hmake-location" `assertHasCommentLine`
"hmake-location"
2713 " -- hpc-location" `assertHasCommentLine`
"hpc-location"
2714 " -- hscolour-location" `assertHasCommentLine`
"hscolour-location"
2715 " -- jhc-location" `assertHasCommentLine`
"jhc-location"
2716 " -- ld-location" `assertHasCommentLine`
"ld-location"
2717 " -- pkg-config-location" `assertHasCommentLine`
"pkg-config-location"
2718 " -- runghc-location" `assertHasCommentLine`
"runghc-location"
2719 " -- strip-location" `assertHasCommentLine`
"strip-location"
2720 " -- tar-location" `assertHasCommentLine`
"tar-location"
2721 " -- uhc-location" `assertHasCommentLine`
"uhc-location"
2723 " -- alex-options" `assertHasCommentLine`
"alex-options"
2724 " -- ar-options" `assertHasCommentLine`
"ar-options"
2725 " -- c2hs-options" `assertHasCommentLine`
"c2hs-options"
2726 " -- cpphs-options" `assertHasCommentLine`
"cpphs-options"
2727 " -- doctest-options" `assertHasCommentLine`
"doctest-options"
2728 " -- gcc-options" `assertHasCommentLine`
"gcc-options"
2729 " -- ghc-options" `assertHasCommentLine`
"ghc-options"
2730 " -- ghc-pkg-options" `assertHasCommentLine`
"ghc-pkg-options"
2731 " -- ghcjs-options" `assertHasCommentLine`
"ghcjs-options"
2732 " -- ghcjs-pkg-options" `assertHasCommentLine`
"ghcjs-pkg-options"
2733 " -- greencard-options" `assertHasCommentLine`
"greencard-options"
2734 " -- haddock-options" `assertHasCommentLine`
"haddock-options"
2735 " -- happy-options" `assertHasCommentLine`
"happy-options"
2736 " -- haskell-suite-options" `assertHasCommentLine`
"haskell-suite-options"
2737 " -- haskell-suite-pkg-options" `assertHasCommentLine`
"haskell-suite-pkg-options"
2738 " -- hmake-options" `assertHasCommentLine`
"hmake-options"
2739 " -- hpc-options" `assertHasCommentLine`
"hpc-options"
2740 " -- hsc2hs-options" `assertHasCommentLine`
"hsc2hs-options"
2741 " -- hscolour-options" `assertHasCommentLine`
"hscolour-options"
2742 " -- jhc-options" `assertHasCommentLine`
"jhc-options"
2743 " -- ld-options" `assertHasCommentLine`
"ld-options"
2744 " -- pkg-config-options" `assertHasCommentLine`
"pkg-config-options"
2745 " -- runghc-options" `assertHasCommentLine`
"runghc-options"
2746 " -- strip-options" `assertHasCommentLine`
"strip-options"
2747 " -- tar-options" `assertHasCommentLine`
"tar-options"
2748 " -- uhc-options" `assertHasCommentLine`
"uhc-options"
2750 testIgnoreProjectFlag
:: Assertion
2751 testIgnoreProjectFlag
= do
2752 -- Coverage flag should be false globally by default (~/.cabal folder)
2753 (_
, _
, prjConfigGlobal
, _
, _
) <- configureProject testdir ignoreSetConfig
2754 let globalCoverageFlag
= packageConfigCoverage
. projectConfigLocalPackages
$ prjConfigGlobal
2755 False @=? Flag
.fromFlagOrDefault
False globalCoverageFlag
2756 -- It is set to true in the cabal.project file
2757 (_
, _
, prjConfigLocal
, _
, _
) <- configureProject testdir emptyConfig
2758 let localCoverageFlag
= packageConfigCoverage
. projectConfigLocalPackages
$ prjConfigLocal
2759 True @=? Flag
.fromFlagOrDefault
False localCoverageFlag
2761 testdir
= "build/ignore-project"
2762 emptyConfig
= mempty
2763 ignoreSetConfig
:: ProjectConfig
2764 ignoreSetConfig
= mempty
{projectConfigShared
= mempty
{projectConfigIgnoreProject
= Flag
True}}
2766 cleanHaddockProject
:: FilePath -> IO ()
2767 cleanHaddockProject testdir
= do
2768 cleanProject testdir
2769 let haddocksdir
= basedir
</> testdir
</> "haddocks"
2770 alreadyExists
<- doesDirectoryExist haddocksdir
2771 when alreadyExists
$ removePathForcibly haddocksdir
2772 let storedir
= basedir
</> testdir
</> "store"
2773 alreadyExists
' <- doesDirectoryExist storedir
2774 when alreadyExists
' $ removePathForcibly storedir
2776 testHaddockProjectDependencies
:: ProjectConfig
-> Assertion
2777 testHaddockProjectDependencies config
= do
2778 (_
, _
, sharedConfig
) <- planProject testdir config
2779 -- `haddock-project` is only supported by `haddock-2.26.1` and above which is
2780 -- shipped with `ghc-9.4`
2781 when (compilerVersion
(pkgConfigCompiler sharedConfig
) > mkVersion
[9, 4]) $ do
2782 let dir
= basedir
</> testdir
2783 cleanHaddockProject testdir
2784 withCurrentDirectory dir
$ do
2785 CmdHaddockProject
.haddockProjectAction
2786 defaultHaddockProjectFlags
2787 { haddockProjectCommonFlags
=
2788 defaultCommonSetupFlags
2789 { setupVerbosity
= Flag verbosity
2793 defaultGlobalFlags
{globalStoreDir
= Flag
"store"}
2795 let haddock
= "haddocks" </> "async" </> "async.haddock"
2796 hasHaddock
<- doesFileExist haddock
2797 unless hasHaddock
$ assertFailure
("File `" ++ haddock
++ "` does not exist.")
2798 cleanHaddockProject testdir
2800 testdir
= "haddock-project/dependencies"