Oracles.hs 2.01 KB
Newer Older
1
module Oracles (
2
    module Oracles.Base,
3
    configOracle, packageDataOracle, dependencyOracle
4
5
    ) where

6
import Development.Shake.Config
Andrey Mokhov's avatar
Andrey Mokhov committed
7
import Development.Shake.Util
8
9
import qualified Data.HashMap.Strict as M
import Base
10
import Util
11
import Config
12
import Control.Monad.Extra
13
14
import Oracles.Base
import Oracles.PackageData
Andrey Mokhov's avatar
Andrey Mokhov committed
15
import Oracles.DependencyList
16

Andrey Mokhov's avatar
Andrey Mokhov committed
17
-- Oracle for configuration files
Andrey Mokhov's avatar
Andrey Mokhov committed
18
19
configOracle :: Rules ()
configOracle = do
20
    let configFile = cfgPath </> "system.config"
21
    cfg <- newCache $ \() -> do
22
23
        unlessM (doesFileExist $ configFile <.> "in") $
            redError_ $ "\nConfiguration file '" ++ (configFile <.> "in")
Andrey Mokhov's avatar
Andrey Mokhov committed
24
                      ++ "' is missing; unwilling to proceed."
25
26
27
        need [configFile]
        putOracle $ "Reading " ++ unifyPath configFile ++ "..."
        liftIO $ readConfigFile configFile
28
    addOracle $ \(ConfigKey key) -> M.lookup key <$> cfg ()
Andrey Mokhov's avatar
Andrey Mokhov committed
29
    return ()
30

Andrey Mokhov's avatar
Andrey Mokhov committed
31
-- Oracle for 'package-data.mk' files
Andrey Mokhov's avatar
Andrey Mokhov committed
32
33
packageDataOracle :: Rules ()
packageDataOracle = do
34
35
    pkgData <- newCache $ \file -> do
        need [file]
Andrey Mokhov's avatar
Andrey Mokhov committed
36
        putOracle $ "Reading " ++ file ++ "..."
37
        liftIO $ readConfigFile file
38
39
    addOracle $ \(PackageDataKey (file, key)) ->
        M.lookup key <$> pkgData (unifyPath file)
40
    return ()
Andrey Mokhov's avatar
Andrey Mokhov committed
41

42
43
44
bimap :: (a -> b) -> (c -> d) -> (a, c) -> (b, d)
bimap f g (x, y) = (f x, g y)

Andrey Mokhov's avatar
Andrey Mokhov committed
45
46
47
-- Oracle for 'path/dist/*.deps' files
dependencyOracle :: Rules ()
dependencyOracle = do
48
49
    deps <- newCache $ \file -> do
        need [file]
Andrey Mokhov's avatar
Andrey Mokhov committed
50
        putOracle $ "Reading " ++ file ++ "..."
51
        contents <- parseMakefile <$> (liftIO $ readFile file)
Andrey Mokhov's avatar
Andrey Mokhov committed
52
        return $ M.fromList
53
               $ map (bimap unifyPath (map unifyPath))
Andrey Mokhov's avatar
Andrey Mokhov committed
54
55
56
               $ map (bimap head concat . unzip)
               $ groupBy ((==) `on` fst)
               $ sortBy (compare `on` fst) contents
57
    addOracle $ \(DependencyListKey (file, obj)) ->
58
        M.lookup (unifyPath obj) <$> deps (unifyPath file)
Andrey Mokhov's avatar
Andrey Mokhov committed
59
60
61
62
63
    return ()

-- Make oracle's output more distinguishable
putOracle :: String -> Action ()
putOracle = putColoured Blue