diff options
author | Andrey Mokhov <andrey.mokhov@gmail.com> | 2017-11-06 22:59:38 +0000 |
---|---|---|
committer | Andrey Mokhov <andrey.mokhov@gmail.com> | 2017-11-06 22:59:38 +0000 |
commit | 5cee48036ed69ae298a599d43cf72e0fe73e3b4e (patch) | |
tree | 5fe732c738a769d02e732469f4ffecd4ac9e191a /hadrian/src/Hadrian/Haskell/Cabal/Parse.hs | |
parent | 275ac8ef0a0081f16abbfb8934e10cf271573768 (diff) | |
parent | 7b0b9f603bb1215e2b7af23c2404d637b95a4988 (diff) | |
download | haskell-5cee48036ed69ae298a599d43cf72e0fe73e3b4e.tar.gz |
Merge commit '7b0b9f603bb1215e2b7af23c2404d637b95a4988' as 'hadrian'
Diffstat (limited to 'hadrian/src/Hadrian/Haskell/Cabal/Parse.hs')
-rw-r--r-- | hadrian/src/Hadrian/Haskell/Cabal/Parse.hs | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/hadrian/src/Hadrian/Haskell/Cabal/Parse.hs b/hadrian/src/Hadrian/Haskell/Cabal/Parse.hs new file mode 100644 index 0000000000..578eeacc52 --- /dev/null +++ b/hadrian/src/Hadrian/Haskell/Cabal/Parse.hs @@ -0,0 +1,63 @@ +----------------------------------------------------------------------------- +-- | +-- Module : Hadrian.Haskell.Cabal.Parse +-- Copyright : (c) Andrey Mokhov 2014-2017 +-- License : MIT (see the file LICENSE) +-- Maintainer : andrey.mokhov@gmail.com +-- Stability : experimental +-- +-- Extracting Haskell package metadata stored in Cabal files. +----------------------------------------------------------------------------- +module Hadrian.Haskell.Cabal.Parse (Cabal (..), parseCabal) where + +import Data.List.Extra +import Development.Shake +import Development.Shake.Classes +import qualified Distribution.Package as C +import qualified Distribution.PackageDescription as C +import qualified Distribution.PackageDescription.Parse as C +import qualified Distribution.Text as C +import qualified Distribution.Types.CondTree as C +import qualified Distribution.Verbosity as C + +import Hadrian.Package + +-- TODO: Use fine-grain tracking instead of tracking the whole Cabal file. +-- | Haskell package metadata extracted from a Cabal file. +data Cabal = Cabal + { dependencies :: [PackageName] + , name :: PackageName + , synopsis :: String + , version :: String + } deriving (Eq, Read, Show, Typeable) + +instance Binary Cabal where + put = put . show + get = fmap read get + +instance Hashable Cabal where + hashWithSalt salt = hashWithSalt salt . show + +instance NFData Cabal where + rnf (Cabal a b c d) = a `seq` b `seq` c `seq` d `seq` () + +-- | Parse a Cabal file. +parseCabal :: FilePath -> IO Cabal +parseCabal file = do + gpd <- liftIO $ C.readGenericPackageDescription C.silent file + let pd = C.packageDescription gpd + pkgId = C.package pd + name = C.unPackageName (C.pkgName pkgId) + version = C.display (C.pkgVersion pkgId) + libDeps = collectDeps (C.condLibrary gpd) + exeDeps = map (collectDeps . Just . snd) (C.condExecutables gpd) + allDeps = concat (libDeps : exeDeps) + sorted = sort [ C.unPackageName p | C.Dependency p _ <- allDeps ] + deps = nubOrd sorted \\ [name] + return $ Cabal deps name (C.synopsis pd) version + +collectDeps :: Maybe (C.CondTree v [C.Dependency] a) -> [C.Dependency] +collectDeps Nothing = [] +collectDeps (Just (C.CondNode _ deps ifs)) = deps ++ concatMap f ifs + where + f (C.CondBranch _ t mt) = collectDeps (Just t) ++ collectDeps mt |