Cabal.hs 1.95 KB
Newer Older
Andrey Mokhov's avatar
Andrey Mokhov committed
1
2
3
4
5
6
7
8
9
10
11
-----------------------------------------------------------------------------
-- |
-- Module     : Hadrian.Haskell.Cabal
-- Copyright  : (c) Andrey Mokhov 2014-2017
-- License    : MIT (see the file LICENSE)
-- Maintainer : andrey.mokhov@gmail.com
-- Stability  : experimental
--
-- Basic functionality for extracting Haskell package metadata stored in
-- @.cabal@ files.
-----------------------------------------------------------------------------
12
13
14
15
16
17
18
19
20
21
module Hadrian.Haskell.Cabal (readCabal, cabalNameVersion, cabalDependencies) where

import Development.Shake
import Distribution.Package
import Distribution.PackageDescription
import Distribution.PackageDescription.Parse
import Distribution.Text
import Distribution.Types.CondTree
import Distribution.Verbosity

Andrey Mokhov's avatar
Andrey Mokhov committed
22
23
-- | Read a given @.cabal@ file and return the 'GenericPackageDescription'. The
-- @.cabal@ file is tracked.
24
25
26
27
28
readCabal :: FilePath -> Action GenericPackageDescription
readCabal cabal = do
    need [cabal]
    liftIO $ readGenericPackageDescription silent cabal

Andrey Mokhov's avatar
Andrey Mokhov committed
29
30
-- | Read a given @.cabal@ file and return the package name and version. The
-- @.cabal@ file is tracked.
31
32
33
34
35
cabalNameVersion :: FilePath -> Action (String, String)
cabalNameVersion cabal = do
    identifier <- package . packageDescription <$> readCabal cabal
    return (unPackageName $ pkgName identifier, display $ pkgVersion identifier)

Andrey Mokhov's avatar
Andrey Mokhov committed
36
37
-- | Read a given @.cabal@ file and return the package dependencies. The
-- @.cabal@ file is tracked.
38
39
40
cabalDependencies :: FilePath -> Action [String]
cabalDependencies cabal = do
    gpd <- readCabal cabal
Andrey Mokhov's avatar
Andrey Mokhov committed
41
42
43
    let libDeps = collectDeps (condLibrary gpd)
        exeDeps = map (collectDeps . Just . snd) (condExecutables gpd)
    return [ unPackageName p | Dependency p _ <- concat (libDeps : exeDeps) ]
44
45
46
47
48
49

collectDeps :: Maybe (CondTree v [Dependency] a) -> [Dependency]
collectDeps Nothing = []
collectDeps (Just (CondNode _ deps ifs)) = deps ++ concatMap f ifs
  where
    f (CondBranch _ t mt) = collectDeps (Just t) ++ collectDeps mt