git.iko.soy/typeable/cabal2nix
on master help sign in
Distribution.NixOS: refactor our code into re-usable general-purpose data types
49165f2Peter Simons
src/Distribution/NixOS/Derivation/Cabal.hsnew file+96
@@ -0,0 +1,96 @@
1+module Distribution.NixOS.Derivation.Cabal where
2+
3+import Distribution.NixOS.Derivation.PrettyPrinting
4+import Distribution.NixOS.Derivation.Meta
5+import Distribution.NixOS.Derivation.License
6+import Distribution.Package
7+import Distribution.Text
8+import Data.Version
9+import Data.List
10+import Text.PrettyPrint
11+import Text.ParserCombinators.ReadP ( readP_to_S )
12+import Text.Regex.Posix
13+
14+data Derivation = MkDerivation
15+ { pname :: PackageName
16+ , version :: Version
17+ , sha256 :: String
18+ , isLibrary :: Bool
19+ , isExecutable :: Bool
20+ , buildDepends :: [String]
21+ , buildTools :: [String]
22+ , extraLibs :: [String]
23+ , pkgConfDeps :: [String]
24+ , runHaddock :: Bool
25+ , metaSection :: Meta
26+ }
27+ deriving (Show, Eq, Ord)
28+
29+instance Text Derivation where
30+ disp = renderDerivation
31+ parse = error "parsing Distribution.NixOS.Derivation.Cabal.Derivation is not supported yet"
32+
33+renderDerivation :: Derivation -> Doc
34+renderDerivation deriv = funargs (map text ("cabal" : inputs)) $$ vcat
35+ [ text ""
36+ , text "cabal.mkDerivation" <+> lparen <> text "self" <> colon <+> lbrace
37+ , nest 2 $ vcat
38+ [ attr "pname" $ doubleQuotes (disp (pname deriv))
39+ , attr "version" $ doubleQuotes (disp (version deriv))
40+ , attr "sha256" $ string (sha256 deriv)
41+ , boolattr "isLibrary" (not (isLibrary deriv) || (isExecutable deriv)) (isLibrary deriv)
42+ , boolattr "isExecutable" (not (isLibrary deriv) || (isExecutable deriv)) (isExecutable deriv)
43+ , listattr "buildDepends" (buildDepends deriv)
44+ , listattr "buildTools" (buildTools deriv)
45+ , listattr "extraLibraries" (extraLibs deriv)
46+ , listattr "pkgconfigDepends" (pkgConfDeps deriv)
47+ , boolattr "noHaddock" (not (runHaddock deriv)) (not (runHaddock deriv))
48+ , disp (metaSection deriv)
49+ ]
50+ , rbrace <> rparen
51+ , text ""
52+ ]
53+ where
54+ inputs = nub $ sort $ filter (/="cabal") $ buildDepends deriv ++ buildTools deriv ++ extraLibs deriv ++ pkgConfDeps deriv
55+
56+parseDerivation :: String -> Maybe Derivation
57+parseDerivation buf
58+ | buf =~ "cabal.mkDerivation"
59+ , [name] <- buf `regsubmatch` "pname *= *\"([^\"]+)\""
60+ , [vers] <- buf `regsubmatch` "version *= *\"([^\"]+)\""
61+ , [sha] <- buf `regsubmatch` "sha256 *= *\"([^\"]+)\""
62+ , plats <- buf `regsubmatch` "platforms *= *([^;]+);"
63+ , maint <- buf `regsubmatch` "maintainers *= *\\[([^\"]+)]"
64+ , noHaddock <- buf `regsubmatch` "noHaddock *= *(true|false) *;"
65+ = Just $ MkDerivation
66+ { pname = PackageName name
67+ , version = readVersion vers
68+ , sha256 = sha
69+ , isLibrary = False
70+ , isExecutable = False
71+ , buildDepends = []
72+ , buildTools = []
73+ , extraLibs = []
74+ , pkgConfDeps = []
75+ , runHaddock = case noHaddock of "true":[] -> False
76+ _ -> True
77+ , metaSection = Meta
78+ { homepage = ""
79+ , description = ""
80+ , license = Unknown Nothing
81+ , maintainers = concatMap words maint
82+ , platforms = concatMap words (map (map (\c -> if c == '+' then ' ' else c)) plats)
83+ }
84+ }
85+ | otherwise = Nothing
86+
87+regsubmatch :: String -> String -> [String]
88+regsubmatch buf patt = let (_,_,_,x) = f in x
89+ where f :: (String,String,String,[String])
90+ f = match (makeRegexOpts compExtended execBlank patt) buf
91+
92+readVersion :: String -> Version
93+readVersion str =
94+ case [ v | (v,[]) <- readP_to_S parseVersion str ] of
95+ [ v' ] -> v'
96+ _ -> error ("invalid version specifier " ++ show str)
src/Distribution/NixOS/Derivation/License.hsnew file+56
@@ -0,0 +1,56 @@
1+module Distribution.NixOS.Derivation.License where
2+
3+-- import qualified Distribution.Package as Cabal
4+-- import qualified Distribution.PackageDescription as Cabal
5+import qualified Distribution.License as Cabal
6+-- import Distribution.Package
7+import Data.Version
8+-- import Distribution.PackageDescription
9+-- import Distribution.PackageDescription.Configuration
10+
11+import Distribution.Text
12+import Text.PrettyPrint
13+
14+data License
15+ = GPL2
16+ | GPL3
17+ | LGPL21
18+ | LGPL3
19+ | BSD3
20+ | BSD4
21+ | MIT
22+ | PublicDomain
23+ | Proprietary
24+ | Unknown (Maybe String)
25+ deriving (Eq, Ord)
26+
27+instance Show License where
28+ show GPL2 = "self.stdenv.lib.licenses.gpl2"
29+ show GPL3 = "self.stdenv.lib.licenses.gpl3"
30+ show LGPL21 = "self.stdenv.lib.licenses.lgpl21"
31+ show LGPL3 = "self.stdenv.lib.licenses.gpl3"
32+ show BSD3 = "self.stdenv.lib.licenses.bsd3"
33+ show BSD4 = "self.stdenv.lib.licenses.bsd4"
34+ show MIT = "self.stdenv.lib.licenses.mit"
35+ show PublicDomain = "self.stdenv.lib.licenses.publicDomain"
36+ show Proprietary = "self.stdenv.lib.licenses.proprietary"
37+ show (Unknown lic) = show (maybe "unknown" id lic)
38+
39+instance Text License where
40+ disp = text . show
41+ parse = error "parsing Distribution.NixOS.Derivation.License is not supported yet"
42+
43+fromCabalLicense :: Cabal.License -> License
44+fromCabalLicense (Cabal.GPL Nothing) = Unknown (Just "GPL")
45+fromCabalLicense (Cabal.GPL (Just (Version [2] []))) = GPL2
46+fromCabalLicense (Cabal.GPL (Just (Version [3] []))) = GPL3
47+fromCabalLicense (Cabal.LGPL Nothing) = Unknown (Just "LGPL")
48+fromCabalLicense (Cabal.LGPL (Just (Version [2,1] []))) = LGPL21
49+fromCabalLicense (Cabal.LGPL (Just (Version [3] []))) = LGPL3
50+fromCabalLicense Cabal.BSD3 = BSD3
51+fromCabalLicense Cabal.BSD4 = BSD4
52+fromCabalLicense Cabal.MIT = MIT
53+fromCabalLicense Cabal.PublicDomain = PublicDomain
54+fromCabalLicense Cabal.AllRightsReserved = Proprietary
55+fromCabalLicense Cabal.OtherLicense = Unknown Nothing
56+fromCabalLicense l = error $ "Distribution.NixOS.Derivation.License.fromCabalLicense: unknown license " ++ show l
src/Distribution/NixOS/Derivation/Meta.hsnew file+36
@@ -0,0 +1,36 @@
1+module Distribution.NixOS.Derivation.Meta where
2+
3+import Distribution.NixOS.Derivation.PrettyPrinting
4+import Distribution.NixOS.Derivation.License
5+import Distribution.Text
6+-- import Data.Version
7+import Text.PrettyPrint
8+
9+data Meta = Meta
10+ { homepage :: String
11+ , description :: String
12+ , license :: License
13+ , platforms :: [String]
14+ , maintainers :: [String]
15+ }
16+ deriving (Show, Eq, Ord)
17+
18+instance Text Meta where
19+ disp = renderMeta
20+ parse = error "parsing Distribution.NixOS.Derivation.Cabal.Meta is not supported yet"
21+
22+renderMeta :: Meta -> Doc
23+renderMeta meta = vcat
24+ [ text "meta" <+> equals <+> lbrace
25+ , nest 2 $ vcat
26+ [ onlyIf (homepage meta) $ attr "homepage" $ string (homepage meta)
27+ , onlyIf (description meta) $ attr "description" $ string (description meta)
28+ , attr "license" $ disp (license meta)
29+ , onlyIf (platforms meta) $ sep
30+ [ text "platforms" <+> equals
31+ , nest 2 ((fsep $ punctuate (text " ++") $ map text (platforms meta))) <> semi
32+ ]
33+ , listattr "maintainers" (maintainers meta)
34+ ]
35+ , rbrace <> semi
36+ ]
src/Distribution/NixOS/Derivation/PrettyPrinting.hsnew file+39
@@ -0,0 +1,39 @@
1+module Distribution.NixOS.Derivation.PrettyPrinting where
2+
3+import Text.PrettyPrint
4+
5+-- Pretty-printing helpers for Nix expressions.
6+
7+attr :: String -> Doc -> Doc
8+attr n v = text n <+> equals <+> v <> semi
9+
10+onlyIf :: [a] -> Doc -> Doc
11+onlyIf p d = if not (null p) then d else empty
12+
13+boolattr :: String -> Bool -> Bool -> Doc
14+boolattr n p v = if p then attr n (bool v) else empty
15+
16+listattr :: String -> [String] -> Doc
17+listattr n vs = onlyIf vs $
18+ sep [ text n <+> equals <+> lbrack,
19+ nest 2 $ fsep $ map text vs,
20+ rbrack <> semi
21+ ]
22+
23+bool :: Bool -> Doc
24+bool True = text "true"
25+bool False = text "false"
26+
27+string :: String -> Doc
28+string = doubleQuotes . text
29+
30+prepunctuate :: Doc -> [Doc] -> [Doc]
31+prepunctuate _ [] = []
32+prepunctuate p (d:ds) = d : map (p <>) ds
33+
34+funargs :: [Doc] -> Doc
35+funargs xs = sep [
36+ lbrace <+> (fcat $ prepunctuate (comma <> text " ") $
37+ map (nest 2) xs),
38+ rbrace <> colon
39+ ]