summaryrefslogtreecommitdiff
path: root/src/Autonix/KF5.hs
blob: 1811e6b7dac21e90d5318a9679c451b5d1c4aa2c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}

module Autonix.KF5 where

import Control.Lens
import Control.Monad.IO.Class
import Control.Monad.State
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as B
import Data.Conduit
import Data.List (isPrefixOf)
import Data.Map (Map)
import Data.Monoid
import qualified Data.Set as S
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import System.FilePath (takeBaseName, takeExtensions, takeFileName)

import Autonix.Analyze
import Autonix.CMake
import Autonix.Package (Package)
import qualified Autonix.Package as Package
import Autonix.Regex
import Autonix.Renames

printFilePaths :: MonadIO m => Analyzer m
printFilePaths _ _ = awaitForever $ \(path, _) -> liftIO $ putStrLn path

findKF5Components :: (MonadIO m, MonadState (Map Text Package, Renames) m) => Analyzer m
findKF5Components pkg _ = awaitForever $ \(path, contents) ->
    when ("CMakeLists.txt" == takeFileName path) $ do
        let new = S.fromList
                  $ map ("kf5" <>)
                  $ map (T.toLower . T.decodeUtf8)
                  $ filter (not . cmakeReserved)
                  $ filter (not . B.null)
                  $ concatMap B.words
                  $ concatMap (take 1 . drop 1)
                  $ match regex contents
            regex = makeRegex
                    "find_package[[:space:]]*\\([[:space:]]*KF5\
                    \[[:space:]]*([#\\.${}_[:alnum:][:space:]]+)\\)"
        _1 . ix pkg . Package.buildInputs <>= new

propagateKF5Deps :: (MonadIO m, MonadState (Map Text Package, Renames) m) => Analyzer m
propagateKF5Deps pkg _ = awaitForever $ \(path, contents) ->
  when (".cmake" `isPrefixOf` takeExtensions path) $ do
    let base = T.pack $ takeBaseName $ takeBaseName path
        regex = makeRegex
                "find_dependency[[:space:]]*\\([[:space:]]*\
                \([^[:space:],$\\)]+)"
    case T.splitAt (T.length base - 6) base of
      (upstream, "Config") -> do
        let new = S.fromList
                  $ map (T.toLower . T.decodeUtf8)
                  $ filter (not . cmakeReserved)
                  $ filter (not . B.null)
                  $ concatMap (take 1 . drop 1)
                  $ match regex contents
        _1 . ix pkg . Package.propagatedBuildInputs <>= new
        _2 . at (T.toLower upstream) .= Just pkg
      _ -> return ()

findQt5Components :: (MonadIO m, MonadState (Map Text Package, Renames) m) => Analyzer m
findQt5Components pkg _ = awaitForever $ \(path, contents) ->
    when ("CMakeLists.txt" == takeFileName path) $ do
        let new = S.fromList
                  $ map ("qt5" <>)
                  $ map (T.toLower . T.decodeUtf8)
                  $ filter (not . cmakeReserved)
                  $ filter (not . B.null)
                  $ concatMap B.words
                  $ concatMap (take 1 . drop 1)
                  $ match regex contents
            regex = makeRegex
                    "find_package[[:space:]]*\\([[:space:]]*Qt5\
                    \[[:space:]]*([#\\.${}_[:alnum:][:space:]]+)\\)"
        _1 . ix pkg . Package.buildInputs <>= new

cmakeReserved :: ByteString -> Bool
cmakeReserved bs = or $ map ($ bs)
                   [ B.elem '$'
                   , B.elem '{'
                   , B.elem '}'
                   , B.elem '#'
                   , B.elem '.'
                   , (==) "COMPONENTS"
                   , (==) "REQUIRED"
                   , (==) "CONFIG"
                   , (==) "NO_MODULE"
                   , (==) "QUIET"
                   , (==) "CTest"
                   ]

kf5Analyzers :: (MonadIO m, MonadState (Map Text Package, Renames) m) => [Analyzer m]
kf5Analyzers =
  [ findKF5Components
  , findQt5Components
  , propagateKF5Deps
  ]
  ++ cmakeAnalyzers