PackageData.hs 4.26 KB
Newer Older
1
{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving #-}
2
module Oracles.PackageData (
3
4
    PackageData (..), PackageDataList (..),
    pkgData, pkgDataList, packageDataOracle
5
6
    ) where

7
import Development.Shake.Config
8
import Base
9
import qualified Data.HashMap.Strict as Map
10

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

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
data PackageDataList = CcArgs             FilePath
                     | CSrcs              FilePath
                     | CppArgs            FilePath
                     | DepCcArgs          FilePath
                     | DepExtraLibs       FilePath
                     | DepIds             FilePath
                     | DepIncludeDirs     FilePath
                     | DepLdArgs          FilePath
                     | DepLibDirs         FilePath
                     | DepNames           FilePath
                     | Deps               FilePath
                     | HiddenModules      FilePath
                     | HsArgs             FilePath
                     | IncludeDirs        FilePath
                     | LdArgs             FilePath
                     | Modules            FilePath
                     | SrcDirs            FilePath
                     | TransitiveDepNames FilePath
42
43

newtype PackageDataKey = PackageDataKey (FilePath, String)
44
    deriving (Show, Typeable, Eq, Hashable, Binary, NFData)
45

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

56
pkgData :: PackageData -> Action String
57
pkgData packageData = case packageData of
58
    BuildGhciLib path -> askPackageData path "BUILD_GHCI_LIB"
59
    ComponentId  path -> askPackageData path "COMPONENT_ID"
60
    Synopsis     path -> askPackageData path "SYNOPSIS"
61
    Version      path -> askPackageData path "VERSION"
62

63
pkgDataList :: PackageDataList -> Action [String]
64
pkgDataList packageData = fmap (map unquote . words) $ case packageData of
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
    CcArgs             path -> askPackageData path "CC_OPTS"
    CSrcs              path -> askPackageData path "C_SRCS"
    CppArgs            path -> askPackageData path "CPP_OPTS"
    DepCcArgs          path -> askPackageData path "DEP_CC_OPTS"
    DepExtraLibs       path -> askPackageData path "DEP_EXTRA_LIBS"
    DepIds             path -> askPackageData path "DEP_IPIDS"
    DepIncludeDirs     path -> askPackageData path "DEP_INCLUDE_DIRS_SINGLE_QUOTED"
    DepLibDirs         path -> askPackageData path "DEP_LIB_DIRS_SINGLE_QUOTED"
    DepLdArgs          path -> askPackageData path "DEP_LD_OPTS"
    DepNames           path -> askPackageData path "DEP_NAMES"
    Deps               path -> askPackageData path "DEPS"
    HiddenModules      path -> askPackageData path "HIDDEN_MODULES"
    HsArgs             path -> askPackageData path "HC_OPTS"
    IncludeDirs        path -> askPackageData path "INCLUDE_DIRS"
    LdArgs             path -> askPackageData path "LD_OPTS"
    Modules            path -> askPackageData path "MODULES"
    SrcDirs            path -> askPackageData path "HS_SRC_DIRS"
    TransitiveDepNames path -> askPackageData path "TRANSITIVE_DEP_NAMES"
83
84
  where
    unquote = dropWhile (== '\'') . dropWhileEnd (== '\'')
85
86
87
88

-- Oracle for 'package-data.mk' files
packageDataOracle :: Rules ()
packageDataOracle = do
89
    keys <- newCache $ \file -> do
90
91
92
        need [file]
        putOracle $ "Reading " ++ file ++ "..."
        liftIO $ readConfigFile file
93
    _ <- addOracle $ \(PackageDataKey (file, key)) -> Map.lookup key <$> keys file
94
    return ()