@@ -0,0 +1,96 @@
1+module Distribution.NixOS.Derivation.Cabal where
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
10+import Text.PrettyPrint
11+import Text.ParserCombinators.ReadP ( readP_to_S )
12+import Text.Regex.Posix
14+data Derivation = MkDerivation
15+ { pname :: PackageName
19+ , isExecutable :: Bool
20+ , buildDepends :: [String]
21+ , buildTools :: [String]
22+ , extraLibs :: [String]
23+ , pkgConfDeps :: [String]
25+ , metaSection :: Meta
27+ deriving (Show, Eq, Ord)
29+instance Text Derivation where
30+ disp = renderDerivation
31+ parse = error "parsing Distribution.NixOS.Derivation.Cabal.Derivation is not supported yet"
33+renderDerivation :: Derivation -> Doc
34+renderDerivation deriv = funargs (map text ("cabal" : inputs)) $$ vcat
36+ , text "cabal.mkDerivation" <+> lparen <> text "self" <> colon <+> lbrace
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)
54+ inputs = nub $ sort $ filter (/="cabal") $ buildDepends deriv ++ buildTools deriv ++ extraLibs deriv ++ pkgConfDeps deriv
56+parseDerivation :: String -> Maybe Derivation
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
70+ , isExecutable = False
75+ , runHaddock = case noHaddock of "true":[] -> False
80+ , license = Unknown Nothing
81+ , maintainers = concatMap words maint
82+ , platforms = concatMap words (map (map (\c -> if c == '+' then ' ' else c)) plats)
85+ | otherwise = Nothing
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
92+readVersion :: String -> Version
94+ case [ v | (v,[]) <- readP_to_S parseVersion str ] of
96+ _ -> error ("invalid version specifier " ++ show str)