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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
module Autonix.KF5 where
import Control.Lens
import Control.Monad.IO.Class
import Control.Monad.State
import qualified Data.ByteString.Char8 as B
import Data.Conduit
import Data.List (isPrefixOf)
import qualified Data.Map as M
import Data.Maybe (fromMaybe)
import Data.Monoid
import qualified Data.Set as S
import System.FilePath (takeBaseName, takeExtensions, takeFileName)
import Autonix.Analyze
import Autonix.CMake
import Autonix.Deps
import Autonix.Regex
printFilePaths :: MonadIO m => Analyzer m
printFilePaths _ = awaitForever $ \(path, _) -> liftIO $ putStrLn path
renameKF5Pkgs :: (MonadIO m, MonadState Deps m) => Analyzer m
renameKF5Pkgs pkg = awaitForever $ \(path, contents) ->
when (takeFileName path == "metainfo.yaml") $ do
let regex = makeRegex "cmakename:[[:space:]]*([[:alnum:]]*)"
matches = match regex contents
case matches of
((_ : cmakeName : _) : _) -> rename cmakeName pkg
_ -> return ()
propagateKF5Deps :: (MonadIO m, MonadState Deps m) => Analyzer m
propagateKF5Deps newPkg = awaitForever $ \(path, contents) ->
when (".cmake" `isPrefixOf` takeExtensions path) $ do
let base = takeBaseName $ takeBaseName path
regex = makeRegex
"find_dependency[[:space:]]*\\([[:space:]]*\
\([^[:space:],$\\)]+)"
case splitAt (length base - 6) base of
(oldPkg, "Config") -> do
let new = concatMap (take 1 . drop 1) $ match regex contents
rename (B.pack oldPkg) newPkg
at newPkg %=
Just
. (propagatedBuildInputs %~ S.union (S.fromList new))
. fromMaybe mempty
_ -> return ()
findKF5Components :: (MonadIO m, MonadState Deps m) => Analyzer m
findKF5Components pkg = awaitForever $ \(path, contents) ->
when ("CMakeLists.txt" == takeFileName path) $ do
let new = 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:]]+)\\)"
ix pkg . buildInputs %= S.union (S.fromList $ map ("KF5" <>) new)
findQt5Components :: (MonadIO m, MonadState Deps m) => Analyzer m
findQt5Components pkg = awaitForever $ \(path, contents) ->
when ("CMakeLists.txt" == takeFileName path) $ do
let new = 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:]]+)\\)"
ix pkg . buildInputs %= S.union (S.fromList $ map ("Qt5" <>) new)
cmakeReserved :: ByteString -> Bool
cmakeReserved bs = or $ map ($ bs)
[ B.elem '$'
, B.elem '{'
, B.elem '}'
, B.elem '#'
, B.elem '.'
, (==) "COMPONENTS"
, (==) "REQUIRED"
, (==) "CONFIG"
]
kf5Analyzers :: (MonadIO m, MonadState Deps m) => [Analyzer m]
kf5Analyzers =
[ findKF5Components
, findQt5Components
, renameKF5Pkgs
, propagateKF5Deps
]
++ cmakeAnalyzers
kf5PostAnalyze :: MonadState Deps m => m ()
kf5PostAnalyze = do
moveNativeInputs
movePropagatedInputs
moveUserEnvPkgs
moveNativeInputs :: MonadState Deps m => m ()
moveNativeInputs = deps %= M.map makeNative
where
makeNative = execState $ forM_ native $ \dep -> do
hasDep <- use (buildInputs.to (S.member dep))
when hasDep $ do
buildInputs %= S.delete dep
nativeBuildInputs %= S.insert dep
hasPropDep <- use (propagatedBuildInputs.to (S.member dep))
when hasPropDep $ do
propagatedBuildInputs %= S.delete dep
propagatedNativeBuildInputs %= S.insert dep
native = [ "BISON"
, "extra-cmake-modules"
, "FLEX"
, "kdoctools"
, "ki18n"
, "LibXslt"
, "Perl"
, "PythonInterp"
]
movePropagatedInputs :: MonadState Deps m => m ()
movePropagatedInputs = deps %= M.map propagate
where
propagate = execState $ forM_ propagated $ \dep -> do
hasDep <- use (buildInputs.to (S.member dep))
when hasDep $ do
buildInputs %= S.delete dep
propagatedBuildInputs %= S.insert dep
hasNativeDep <- use (nativeBuildInputs.to (S.member dep))
when hasNativeDep $ do
nativeBuildInputs %= S.delete dep
propagatedNativeBuildInputs %= S.insert dep
propagated = [ "extra-cmake-modules" ]
moveUserEnvPkgs :: MonadState Deps m => m ()
moveUserEnvPkgs = deps %= M.map propagate
where
propagate = execState $ forM_ userEnv $ \dep -> do
hasDep <- use (buildInputs.to (S.member dep))
hasNativeDep <- use (buildInputs.to (S.member dep))
hasPropDep <- use (buildInputs.to (S.member dep))
hasPropNativeDep <- use (buildInputs.to (S.member dep))
when (hasDep || hasNativeDep || hasPropDep || hasPropNativeDep)
$ propagatedUserEnvPkgs %= S.insert dep
userEnv = [ "SharedMimeInfo" ]
|