Refactor dependency oracles
[ghc.git] / src / Oracles / PackageData.hs
1 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
2 module Oracles.PackageData (
3 PackageData (..), PackageDataList (..),
4 pkgData, pkgDataList, packageDataOracle
5 ) where
6
7 import Development.Shake.Config
8 import qualified Data.HashMap.Strict as Map
9
10 import Base
11
12 data PackageData = BuildGhciLib FilePath
13 | ComponentId FilePath
14 | Synopsis FilePath
15 | Version FilePath
16
17 data PackageDataList = CcArgs FilePath
18 | CSrcs FilePath
19 | CppArgs FilePath
20 | DepCcArgs FilePath
21 | DepExtraLibs FilePath
22 | DepIds FilePath
23 | DepIncludeDirs FilePath
24 | DepLdArgs FilePath
25 | DepLibDirs FilePath
26 | DepNames FilePath
27 | Deps FilePath
28 | HiddenModules FilePath
29 | HsArgs FilePath
30 | IncludeDirs FilePath
31 | LdArgs FilePath
32 | Modules FilePath
33 | SrcDirs FilePath
34 | TransitiveDepNames FilePath
35
36 newtype PackageDataKey = PackageDataKey (FilePath, String)
37 deriving (Binary, Eq, Hashable, NFData, Show, Typeable)
38
39 askPackageData :: FilePath -> String -> Action String
40 askPackageData path key = do
41 let fullKey = replaceSeparators '_' $ path ++ "_" ++ key
42 file = path -/- "package-data.mk"
43 maybeValue <- askOracle $ PackageDataKey (file, fullKey)
44 case maybeValue of
45 Nothing -> return ""
46 Just value -> return value
47
48 -- | For each @PackageData path@ the file 'path/package-data.mk' contains a line
49 -- of the form 'path_VERSION = 1.2.3.4'. @pkgData (PackageData path)@ is an
50 -- Action that consults the file and returns "1.2.3.4".
51 pkgData :: PackageData -> Action String
52 pkgData packageData = case packageData of
53 BuildGhciLib path -> askPackageData path "BUILD_GHCI_LIB"
54 ComponentId path -> askPackageData path "COMPONENT_ID"
55 Synopsis path -> askPackageData path "SYNOPSIS"
56 Version path -> askPackageData path "VERSION"
57
58 -- | @PackageDataList path@ is used for multiple string options separated by
59 -- spaces, such as @path_MODULES = Data.Array Data.Array.Base ...@.
60 -- @pkgListData Modules@ therefore returns ["Data.Array", "Data.Array.Base", ...]
61 pkgDataList :: PackageDataList -> Action [String]
62 pkgDataList packageData = fmap (map unquote . words) $ case packageData of
63 CcArgs path -> askPackageData path "CC_OPTS"
64 CSrcs path -> askPackageData path "C_SRCS"
65 CppArgs path -> askPackageData path "CPP_OPTS"
66 DepCcArgs path -> askPackageData path "DEP_CC_OPTS"
67 DepExtraLibs path -> askPackageData path "DEP_EXTRA_LIBS"
68 DepIds path -> askPackageData path "DEP_IPIDS"
69 DepIncludeDirs path -> askPackageData path "DEP_INCLUDE_DIRS_SINGLE_QUOTED"
70 DepLibDirs path -> askPackageData path "DEP_LIB_DIRS_SINGLE_QUOTED"
71 DepLdArgs path -> askPackageData path "DEP_LD_OPTS"
72 DepNames path -> askPackageData path "DEP_NAMES"
73 Deps path -> askPackageData path "DEPS"
74 HiddenModules path -> askPackageData path "HIDDEN_MODULES"
75 HsArgs path -> askPackageData path "HC_OPTS"
76 IncludeDirs path -> askPackageData path "INCLUDE_DIRS"
77 LdArgs path -> askPackageData path "LD_OPTS"
78 Modules path -> askPackageData path "MODULES"
79 SrcDirs path -> askPackageData path "HS_SRC_DIRS"
80 TransitiveDepNames path -> askPackageData path "TRANSITIVE_DEP_NAMES"
81 where
82 unquote = dropWhile (== '\'') . dropWhileEnd (== '\'')
83
84 -- | Oracle for 'package-data.mk' files.
85 packageDataOracle :: Rules ()
86 packageDataOracle = do
87 keys <- newCache $ \file -> do
88 need [file]
89 putLoud $ "Reading " ++ file ++ "..."
90 liftIO $ readConfigFile file
91 _ <- addOracle $ \(PackageDataKey (file, key)) -> Map.lookup key <$> keys file
92 return ()