Refactor dependency oracles
[ghc.git] / src / Rules / Cabal.hs
1 module Rules.Cabal (cabalRules) where
2
3 import Data.Version
4 import Distribution.Package as DP
5 import Distribution.PackageDescription
6 import Distribution.PackageDescription.Parse
7 import Distribution.Verbosity
8
9 import Base
10 import Expression
11 import GHC
12 import Settings
13
14 cabalRules :: Rules ()
15 cabalRules = do
16 -- Cache boot package constraints (to be used in cabalArgs).
17 bootPackageConstraints %> \out -> do
18 bootPkgs <- interpretInContext (stageContext Stage0) getPackages
19 let pkgs = filter (\p -> p /= compiler && isLibrary p) bootPkgs
20 constraints <- forM (sort pkgs) $ \pkg -> do
21 need [pkgCabalFile pkg]
22 pd <- liftIO . readPackageDescription silent $ pkgCabalFile pkg
23 let identifier = package . packageDescription $ pd
24 version = showVersion . pkgVersion $ identifier
25 DP.PackageName name = DP.pkgName identifier
26 return $ name ++ " == " ++ version
27 writeFileChanged out . unlines $ constraints
28
29 -- Cache package dependencies.
30 packageDependencies %> \out -> do
31 pkgDeps <- forM (sort knownPackages) $ \pkg ->
32 if pkg `elem` [hp2ps, libffi, rts, touchy, unlit]
33 then return $ pkgNameString pkg
34 else do
35 need [pkgCabalFile pkg]
36 pd <- liftIO . readPackageDescription silent $ pkgCabalFile pkg
37 let depsLib = collectDeps $ condLibrary pd
38 depsExes = map (collectDeps . Just . snd) $ condExecutables pd
39 deps = concat $ depsLib : depsExes
40 depNames = [ name | Dependency (DP.PackageName name) _ <- deps ]
41 return . unwords $ pkgNameString pkg : sort depNames
42 writeFileChanged out . unlines $ pkgDeps
43
44 collectDeps :: Maybe (CondTree v [Dependency] a) -> [Dependency]
45 collectDeps Nothing = []
46 collectDeps (Just (CondNode _ deps ifs)) = deps ++ concatMap f ifs
47 where
48 f (_, t, mt) = collectDeps (Just t) ++ collectDeps mt