bd7b6abe1f4369829b6a7ca383b1d909425aa959
[hadrian.git] / src / Hadrian / Haskell / Cabal / Parse.hs
1 -----------------------------------------------------------------------------
2 -- |
3 -- Module : Hadrian.Haskell.Cabal.Parse
4 -- Copyright : (c) Andrey Mokhov 2014-2017
5 -- License : MIT (see the file LICENSE)
6 -- Maintainer : andrey.mokhov@gmail.com
7 -- Stability : experimental
8 --
9 -- Extracting Haskell package metadata stored in Cabal files.
10 -----------------------------------------------------------------------------
11 module Hadrian.Haskell.Cabal.Parse (Cabal (..), parseCabal) where
12
13 import Data.List.Extra
14 import Development.Shake
15 import qualified Distribution.Package as C
16 import qualified Distribution.PackageDescription as C
17 import qualified Distribution.PackageDescription.Parsec as C
18 import qualified Distribution.Text as C
19 import qualified Distribution.Types.CondTree as C
20 import qualified Distribution.Verbosity as C
21
22 import Hadrian.Haskell.Cabal.Type
23
24 -- | Parse a Cabal file.
25 parseCabal :: FilePath -> IO Cabal
26 parseCabal file = do
27 gpd <- liftIO $ C.readGenericPackageDescription C.silent file
28 let pd = C.packageDescription gpd
29 pkgId = C.package pd
30 name = C.unPackageName (C.pkgName pkgId)
31 version = C.display (C.pkgVersion pkgId)
32 libDeps = collectDeps (C.condLibrary gpd)
33 exeDeps = map (collectDeps . Just . snd) (C.condExecutables gpd)
34 allDeps = concat (libDeps : exeDeps)
35 sorted = sort [ C.unPackageName p | C.Dependency p _ <- allDeps ]
36 deps = nubOrd sorted \\ [name]
37 return $ Cabal deps name (C.synopsis pd) version
38
39 collectDeps :: Maybe (C.CondTree v [C.Dependency] a) -> [C.Dependency]
40 collectDeps Nothing = []
41 collectDeps (Just (C.CondNode _ deps ifs)) = deps ++ concatMap f ifs
42 where
43 f (C.CondBranch _ t mt) = collectDeps (Just t) ++ collectDeps mt