cabal2nix-1.10: src/Cabal2Nix/Package.hs
module Cabal2Nix.Package
( cabal2nix, showNixPkg
, PkgName, PkgVersion, PkgSHA256, PkgURL, PkgDescription, PkgLicense
, PkgIsLib, PkgIsExe, PkgDependencies, PkgBuildTools, PkgExtraLibs
, PkgPkgconfigDeps, PkgPlatforms, PkgMaintainers, PkgNoHaddock, Pkg(..)
)
where
import Data.List
import Data.Maybe
import Distribution.Compiler
import Distribution.Package
import Distribution.PackageDescription
import Distribution.PackageDescription.Configuration
import Distribution.System
import Distribution.Version
import Text.PrettyPrint
import Data.Version ( showVersion )
import Cabal2Nix.License
import Cabal2Nix.Name
import Cabal2Nix.CorePackages
import Cabal2Nix.Pretty
type PkgName = String
type PkgVersion = String
type PkgSHA256 = String
type PkgURL = String
type PkgDescription = String
type PkgLicense = String
type PkgIsLib = Bool
type PkgIsExe = Bool
type PkgDependencies = [Dependency] -- [CondTree ConfVar [Dependency] ()]
type PkgBuildTools = [Dependency]
type PkgExtraLibs = [String]
type PkgPkgconfigDeps = [String]
type PkgNoHaddock = Bool
type PkgPlatforms = [String]
type PkgMaintainers = [String]
data Pkg = Pkg PkgName
PkgVersion
PkgSHA256
PkgURL
PkgDescription
PkgLicense
PkgIsLib
PkgIsExe
PkgDependencies
PkgBuildTools
PkgExtraLibs
PkgPkgconfigDeps
PkgNoHaddock
PkgPlatforms
PkgMaintainers
deriving (Show)
showNixPkg :: Pkg -> String
showNixPkg (Pkg name ver sha256 url desc lic isLib isExe deps
tools libs pcs noHaddock platforms maintainers) =
render doc
where
doc = funargs (map text ("cabal" : pkgInputs)) $$
vcat [
text "",
text "cabal.mkDerivation" <+> lparen <> text "self" <>
colon <+> lbrace,
nest 2 $ vcat [
attr "pname" $ string name,
attr "version" $ string ver,
attr "sha256" $ string sha256,
boolattr "isLibrary" (not isLib || isExe) isLib,
boolattr "isExecutable" (not isLib || isExe) isExe,
listattr "buildDepends" pkgDeps,
listattr "buildTools" pkgBuildTools,
listattr "extraLibraries" pkgLibs,
listattr "pkgconfigDepends" pkgPCs,
boolattr "noHaddock" noHaddock noHaddock,
vcat [
text "meta" <+> equals <+> lbrace,
nest 2 $ vcat [
onlyIf url $ attr "homepage" $ string url,
onlyIf desc $ attr "description" $ string desc,
attr "license" $ text lic,
onlyIf platforms $
sep [
text "platforms" <+> equals,
nest 2 ((fsep $ punctuate (text " ++") $ map text platforms)) <> semi
],
listattr "maintainers" maintainers
],
rbrace <> semi
]
],
rbrace <> rparen,
text ""
]
pkgLibs = nub $ sort $ concatMap libNixName libs
pkgPCs = nub $ sort $ concatMap libNixName pcs
pkgDeps = nub $ sort $ map toNixName $
filter (`notElem` (name : corePackages)) $ map unDep deps
pkgBuildTools = nub $ sort $ map toNixName $
filter (`notElem` coreBuildTools) $ map unDep tools
pkgInputs = nub $ pkgLibs ++ pkgPCs ++ pkgBuildTools ++ pkgDeps
cabal2nix :: GenericPackageDescription -> PkgSHA256 -> PkgNoHaddock -> PkgPlatforms -> PkgMaintainers -> Pkg
cabal2nix cabal sha256 noHaddock platforms maintainers =
Pkg pkgname pkgver sha256 url desc lic
isLib isExe
(buildDepends tpkg)
tools
libs
pcs
noHaddock
[ if '.' `elem` p then p else "self.stdenv.lib.platforms." ++ p | p <- platforms ]
[ if '.' `elem` m then m else "self.stdenv.lib.maintainers." ++ m | m <- maintainers ]
where
pkg = packageDescription cabal
PackageName pkgname = pkgName (package pkg)
pkgver = showVersion (pkgVersion (package pkg))
lic = showLic (license pkg)
url = homepage pkg
desc = normalizeDescription (synopsis pkg)
-- globalDeps = buildDepends pkg
-- Potentially dangerous: determine a default flattening of the
-- package description. Better approach: export the conditional
-- structure and reflect it in the generated file.
Right (tpkg, _) = finalizePackageDescription [] (const True)
(Platform I386 Linux) -- shouldn't be hardcoded
(CompilerId GHC (Version [7,0,4] [])) -- dito
[] cabal
isLib = isJust (library tpkg)
isExe = not (null (executables tpkg))
libDeps = map libBuildInfo $ maybeToList (library tpkg)
exeDeps = map buildInfo $ executables tpkg
libs = concatMap extraLibs (libDeps ++ exeDeps)
pcs = map unDep $ concatMap pkgconfigDepends (libDeps ++ exeDeps)
tools = concatMap buildTools (libDeps ++ exeDeps)
unDep :: Dependency -> String
unDep (Dependency (PackageName x) _) = x
normalizeDescription :: String -> String
normalizeDescription desc
| null desc = []
| last desc == '.' && length (filter ('.'==) desc) == 1 = normalizeDescription (reverse (tail (reverse desc)))
| otherwise = unwords (words desc) >>= quote
quote :: Char -> [Char]
quote '"' = "\\\""
quote c = [c]