PackageData.hs 3.58 KB
Newer Older
1
{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving #-}
2
3

module Oracles.PackageData (
4
5
    PackageData (..), PackageDataList (..),
    pkgData, pkgDataList, packageDataOracle
6
7
    ) where

8
import Base
9
import Util
10
import Data.List
11
12
import Control.Applicative
import qualified Data.HashMap.Strict as Map
13

14
15
-- For each (PackageData path) the file 'path/package-data.mk' contains
-- a line of the form 'path_VERSION = 1.2.3.4'.
16
-- pkgData $ PackageData path is an action that consults the file and
17
18
-- returns "1.2.3.4".
--
19
-- PackageDataList is used for multiple string options separated by spaces,
20
-- such as 'path_MODULES = Data.Array Data.Array.Base ...'.
21
-- pkgListData Modules therefore returns ["Data.Array", "Data.Array.Base", ...]
22
23
data PackageData = Version      FilePath
                 | PackageKey   FilePath
24
                 | LibName      FilePath
25
26
                 | Synopsis     FilePath
                 | BuildGhciLib FilePath
27

28
data PackageDataList = Modules        FilePath
29
                     | HiddenModules  FilePath
30
31
32
                     | SrcDirs        FilePath
                     | IncludeDirs    FilePath
                     | Deps           FilePath
33
                     | DepIds         FilePath
34
35
36
37
38
39
                     | DepNames       FilePath
                     | CppArgs        FilePath
                     | HsArgs         FilePath
                     | CcArgs         FilePath
                     | CSrcs          FilePath
                     | DepIncludeDirs FilePath
40
41

newtype PackageDataKey = PackageDataKey (FilePath, String)
42
    deriving (Show, Typeable, Eq, Hashable, Binary, NFData)
43

44
45
46
askPackageData :: FilePath -> String -> Action String
askPackageData path key = do
    let fullKey = replaceSeparators '_' $ path ++ "_" ++ key
47
48
49
50
51
        file    = path -/- "package-data.mk"
    maybeValue <- askOracle $ PackageDataKey (file, fullKey)
    case maybeValue of
        Nothing    -> putError $ "No key '" ++ key ++ "' in " ++ file ++ "."
        Just value -> return value
52

53
pkgData :: PackageData -> Action String
54
55
56
57
58
59
pkgData packageData = case packageData of
    Version      path -> askPackageData path "VERSION"
    PackageKey   path -> askPackageData path "PACKAGE_KEY"
    LibName      path -> askPackageData path "LIB_NAME"
    Synopsis     path -> askPackageData path "SYNOPSIS"
    BuildGhciLib path -> askPackageData path "BUILD_GHCI_LIB"
60

61
pkgDataList :: PackageDataList -> Action [String]
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
pkgDataList packageData = fmap (map unquote . words) $ case packageData of
    Modules        path -> askPackageData path "MODULES"
    HiddenModules  path -> askPackageData path "HIDDEN_MODULES"
    SrcDirs        path -> askPackageData path "HS_SRC_DIRS"
    IncludeDirs    path -> askPackageData path "INCLUDE_DIRS"
    Deps           path -> askPackageData path "DEPS"
    DepIds         path -> askPackageData path "DEP_IPIDS"
    DepNames       path -> askPackageData path "DEP_NAMES"
    CppArgs        path -> askPackageData path "CPP_OPTS"
    HsArgs         path -> askPackageData path "HC_OPTS"
    CcArgs         path -> askPackageData path "CC_OPTS"
    CSrcs          path -> askPackageData path "C_SRCS"
    DepIncludeDirs path -> askPackageData path "DEP_INCLUDE_DIRS_SINGLE_QUOTED"
  where
    unquote = dropWhile (== '\'') . dropWhileEnd (== '\'')
77
78
79
80

-- Oracle for 'package-data.mk' files
packageDataOracle :: Rules ()
packageDataOracle = do
81
    pkgDataContents <- newCache $ \file -> do
82
83
84
        need [file]
        putOracle $ "Reading " ++ file ++ "..."
        liftIO $ readConfigFile file
85
86
    _ <- addOracle $ \(PackageDataKey (file, key)) ->
        Map.lookup key <$> pkgDataContents file
87
    return ()