summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomasTuegel <>2014-11-12 18:11:00 (GMT)
committerhdiff <hdiff@hdiff.luite.com>2014-11-12 18:11:00 (GMT)
commit1b09e2c9d4efaf79c28aac25a1ceea5d62ae6451 (patch)
tree6ee039dcd8cbd87cc149aacff4bc9b60b6498715
version 0.1.0.00.1.0.0
-rw-r--r--LICENSE30
-rw-r--r--Setup.hs2
-rw-r--r--autonix-deps-kf5.cabal49
-rw-r--r--kf5-deps.hs20
-rw-r--r--src/Autonix/KF5.hs134
5 files changed, 235 insertions, 0 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..c5afa8d
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2014, Thomas Tuegel
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+ * Neither the name of Thomas Tuegel nor the names of other
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
index 0000000..9a994af
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/autonix-deps-kf5.cabal b/autonix-deps-kf5.cabal
new file mode 100644
index 0000000..a5117bd
--- /dev/null
+++ b/autonix-deps-kf5.cabal
@@ -0,0 +1,49 @@
+name: autonix-deps-kf5
+version: 0.1.0.0
+synopsis: Generate dependencies for KDE 5 Nix expressions
+license: BSD3
+license-file: LICENSE
+author: Thomas Tuegel
+maintainer: ttuegel@gmail.com
+copyright: 2014 Thomas Tuegel
+category: System
+build-type: Simple
+cabal-version: >=1.10
+bug-reports: https://github.com/ttuegel/autonix-deps-kf5/issues
+description:
+ @autonix-deps-kf5@ automatically detects dependencies for KDE Frameworks 5
+ and related software collections. The generated dependencies are used to
+ automatically create expressions for use by the Nix package manager.
+
+source-repository head
+ type: git
+ location: https://github.com/ttuegel/autonix-deps-kf5.git
+
+library
+ exposed-modules:
+ Autonix.KF5
+ build-depends:
+ autonix-deps ==0.1.*
+ , base >=4.7 && <5
+ , bytestring >=0.10
+ , conduit ==1.2.*
+ , containers >=0.5
+ , filepath >=1.3
+ , lens >=4.0
+ , mtl >=2.1
+ , transformers >=0.3
+ hs-source-dirs: src
+ default-language: Haskell2010
+ ghc-options: -Wall
+
+executable kf5-deps
+ main-is: kf5-deps.hs
+ build-depends:
+ autonix-deps
+ , autonix-deps-kf5
+ , base
+ , containers
+ , lens
+ , mtl
+ default-language: Haskell2010
+ ghc-options: -Wall \ No newline at end of file
diff --git a/kf5-deps.hs b/kf5-deps.hs
new file mode 100644
index 0000000..637d352
--- /dev/null
+++ b/kf5-deps.hs
@@ -0,0 +1,20 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Main where
+
+import Control.Monad.State
+import Data.Monoid
+
+import Autonix.Analyze
+import Autonix.Args
+import Autonix.Deps
+import Autonix.Generate
+import Autonix.KF5
+
+main :: IO ()
+main = withArgs $ \manifest renames -> flip evalStateT mempty $ do
+ rename "ECM" "extra-cmake-modules"
+ analyzePackages (analyzeFiles kf5Analyzers) manifest renames
+ kf5PostAnalyze
+ get >>= writeDeps
+ get >>= writeRenames
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" ]