git.iko.soy/typeable/cabal2nix
on 9d40586 help sign in
101 lines 3.9 kB history raw
1module Cabal2Nix.Normalize ( normalize, normalizeCabalFlags ) where
3import Cabal2Nix.CorePackages
4import Cabal2Nix.Name
5import Control.Lens
6import Data.Function
7import Data.List
8import Data.Set ( Set )
9import qualified Data.Set as Set
10import Language.Nix.Identifier ( Identifier(..) )
11import Distribution.Nixpkgs.Haskell
12import Distribution.Nixpkgs.Meta
13import Distribution.Nixpkgs.Util.Regex ( regsubmatch )
14import Distribution.Package
15import Distribution.PackageDescription ( FlagAssignment, FlagName(..) )
16import Distribution.Simple.Utils ( lowercase )
18normalize :: Derivation -> Derivation
19normalize drv = drv
20 & over libraryDepends (normalizeBuildInfo (packageName drv))
21 & over executableDepends (normalizeBuildInfo (packageName drv))
22 & over testDepends (normalizeBuildInfo (packageName drv))
23 & over metaSection normalizeMeta
24 & over cabalFlags normalizeCabalFlags
26normalizeBuildInfo :: PackageName -> BuildInfo -> BuildInfo
27normalizeBuildInfo (PackageName pname) bi = bi
28 & haskell . contains (Identifier pname) .~ False
29 & tool . contains (Identifier pname) .~ False
30 & tool %~ normalizeNixBuildTools . Set.filter (\(Identifier n) -> n `notElem` coreBuildTools)
32 {-
33 {
34 , testDepends = normalizeNixNames (Set.delete pname testDepends)
35 , extraLibs = normalizeNixLibs extraLibs
36 , pkgConfDeps = normalizeNixLibs pkgConfDeps
37 , configureFlags = normalizeSet configureFlags
38 }
39-}
41normalizeMeta :: Meta -> Meta
42normalizeMeta = over description normalizeSynopsis
43 . over maintainers normalizeMaintainers
44 . over platforms normalizePlatforms
46normalizeSynopsis :: String -> String
47normalizeSynopsis desc
48 | null desc = []
49 | last desc == '.' && length (filter ('.'==) desc) == 1 = normalizeSynopsis (init desc)
50 | otherwise = quote (unwords (words desc))
52quote :: String -> String
53quote ('\\':c:cs) = '\\' : c : quote cs
54quote ('"':cs) = '\\' : '"' : quote cs
55quote (c:cs) = c : quote cs
56quote [] = []
58normalizeSet :: Set String -> Set String
59normalizeSet = Set.filter (not . null)
61-- normalizeNixNames :: Set String -> Set String
62-- normalizeNixNames = normalizeSet . Set.map toNixName
64-- normalizeNixLibs :: Set String -> Set String
65-- normalizeNixLibs = normalizeSet . Set.fromList . concatMap libNixName . Set.toList
67normalizeNixBuildTools :: Set Identifier -> Set Identifier
68normalizeNixBuildTools = Set.fromList . concatMap buildToolNixName' . Set.toList
69 where
70 buildToolNixName' :: Identifier -> [Identifier]
71 buildToolNixName' (Identifier n) = [ Identifier n' | n' <- buildToolNixName n ]
73-- |Strip any kind of path prefix from maintainer names, filter duplicates, and
74-- sort the resulting list alphabetically.
75--
76-- >>> normalizeMaintainers $ Set.fromList ["self.stdenv.lib.maintainers.foobar", "foobar"]
77-- fromList ["foobar"]
78--
79-- >>> normalizeMaintainers $ Set.fromList ["any.prefix.is.recognized.yo", "abc.def"]
80-- fromList ["def","yo"]
82normalizeMaintainers :: Set String -> Set String
83normalizeMaintainers = normalizeSet . Set.map
84 (\m -> (m `regsubmatch` "^([^.].*\\.)?([^.]+)$") !! 1)
86normalizePlatforms :: Set String -> Set String
87normalizePlatforms = normalizeSet . Set.map
88 (\p -> if '.' `elem` p then p else "stdenv.lib.platforms." ++ p)
91-- |When a flag is specified multiple times, the first occurrence
92-- counts. This is counter-intuitive, IMHO, but it's how cabal does it.
93-- Flag names are spelled in all lowercase.
94--
95-- >>> normalizeCabalFlags [(FlagName "foo", True), (FlagName "FOO", True), (FlagName "Foo", False)]
96-- [(FlagName "foo",True)]
98normalizeCabalFlags :: FlagAssignment -> FlagAssignment
99normalizeCabalFlags flags' = nubBy ((==) `on` fst) (sortBy (compare `on` fst) flags)
100 where
101 flags = [ (FlagName (lowercase n), b) | (FlagName n, b) <- flags' ]