summaryrefslogtreecommitdiff
path: root/src/Autonix/KF5.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Autonix/KF5.hs')
-rw-r--r--src/Autonix/KF5.hs134
1 files changed, 134 insertions, 0 deletions
diff --git a/src/Autonix/KF5.hs b/src/Autonix/KF5.hs
new file mode 100644
index 0000000..c621a37
--- /dev/null
+++ b/src/Autonix/KF5.hs
@@ -0,0 +1,134 @@
+{-# 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)
+
+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, 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" ]