Skip to content
Newer
Older
100644 258 lines (234 sloc) 9.7 KB
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
1 -- A program for generating a Gentoo ebuild from a .cabal file
2 --
3 -- Author : Duncan Coutts <dcoutts@gentoo.org>
4 --
5 -- Created: 21 July 2005
6 --
7 -- Copyright (C) 2005 Duncan Coutts
8 --
9 -- This library is free software; you can redistribute it and/or
10 -- modify it under the terms of the GNU General Public License
11 -- as published by the Free Software Foundation; either version 2
12 -- of the License, or (at your option) any later version.
13 --
14 -- This library is distributed in the hope that it will be useful,
15 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
16 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 -- General Public License for more details.
18 --
19 -- |
20 -- Maintainer : haskell@gentoo.org
21 --
22 -- cabal2ebuild - a program for generating a Gentoo ebuild from a .cabal file
23 --
24 module Cabal2Ebuild
25 (EBuild(..)
26 ,cabal2ebuild
27 ,showEBuild) where
28
29 import qualified Distribution.PackageDescription as Cabal
30 (PackageDescription(..),
31 readPackageDescription)
32 import qualified Distribution.Package as Cabal (PackageIdentifier(..))
33 import qualified Distribution.Version as Cabal (showVersion, Dependency(..),
34 VersionRange(..))
35 import qualified Distribution.License as Cabal (License(..))
36 --import qualified Distribution.Compiler as Cabal (CompilerFlavor(..))
37
8022ddc Adding support for variable substitution in generated ebuilds
der_eq@freenet.de authored
38 import Data.Char (toLower,isUpper)
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
39 import Data.Maybe (catMaybes)
8022ddc Adding support for variable substitution in generated ebuilds
der_eq@freenet.de authored
40 import Text.Regex
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
41
42 data EBuild = EBuild {
43 name :: String,
44 version :: String,
45 description :: String,
46 homepage :: String,
47 src_uri :: String,
48 license :: String,
49 slot :: String,
50 keywords :: [String],
51 iuse :: [String],
52 depend :: [Dependency],
53 features :: [String],
54 -- comments on various fields for communicating stuff to the user
55 licenseComments :: String,
8022ddc Adding support for variable substitution in generated ebuilds
der_eq@freenet.de authored
56 my_pn :: Maybe String --If the package's name contains upper-case
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
57 }
58
59 type Package = String
60 type Version = String
61 type UseFlag = String
62 data Dependency = AnyVersionOf Package
63 | ThisVersionOf Version Package -- =package-version
64 | LaterVersionOf Version Package -- >package-version
65 | EarlierVersionOf Version Package -- <package-version
66 | OrLaterVersionOf Version Package -- >=package-version
67 | OrEarlierVersionOf Version Package -- <=package-version
68 | DependEither Dependency Dependency -- depend || depend
69 | DependIfUse UseFlag Dependency -- use? ( depend )
70
71 ebuildTemplate = EBuild {
72 name = "foobar",
73 version = "0.1",
74 description = "",
75 homepage = "",
76 src_uri = "",
77 license = "",
78 slot = "0",
63b57b8 Adapted HackPort to the new Hackage interface
der_eq@freenet.de authored
79 keywords = ["~amd64","~x86"],
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
80 iuse = [],
81 depend = [],
c81b055 profile and haddock only make sense for lib packages
Duncan Coutts authored
82 features = [],
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
83 licenseComments = "",
8022ddc Adding support for variable substitution in generated ebuilds
der_eq@freenet.de authored
84 my_pn = Nothing
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
85 }
86
87 cabal2ebuild :: Cabal.PackageDescription -> EBuild
88 cabal2ebuild pkg = ebuildTemplate {
8022ddc Adding support for variable substitution in generated ebuilds
der_eq@freenet.de authored
89 name = map toLower cabalPkgName,
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
90 version = Cabal.showVersion (Cabal.pkgVersion (Cabal.package pkg)),
91 description = if null (Cabal.synopsis pkg) then Cabal.description pkg
92 else Cabal.synopsis pkg,
93 homepage = Cabal.homepage pkg,
94 src_uri = Cabal.pkgUrl pkg,
95 license = convertLicense (Cabal.license pkg),
96 licenseComments = licenseComment (Cabal.license pkg),
97 depend = defaultDepGHC
8022ddc Adding support for variable substitution in generated ebuilds
der_eq@freenet.de authored
98 : convertDependencies (Cabal.buildDepends pkg),
20179c4 Set S= properly for packages with upper case names
Duncan Coutts authored
99 my_pn = if any isUpper cabalPkgName then Just cabalPkgName else Nothing,
710dfef Adding support for the "lib" and "bin" feature
der_eq@freenet.de authored
100 features = (features ebuildTemplate)
c81b055 profile and haddock only make sense for lib packages
Duncan Coutts authored
101 ++ maybe [] (const ["profile","haddock", "lib"]) (Cabal.library pkg)
710dfef Adding support for the "lib" and "bin" feature
der_eq@freenet.de authored
102 ++ if null (Cabal.executables pkg) then [] else ["bin"]
8022ddc Adding support for variable substitution in generated ebuilds
der_eq@freenet.de authored
103 } where
104 cabalPkgName = Cabal.pkgName (Cabal.package pkg)
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
105
5bcf377 Update hackport's ebuild generation to current conventions.
Duncan Coutts authored
106 defaultDepGHC = OrLaterVersionOf "6.4.2" "dev-lang/ghc"
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
107
108 -- map the cabal license type to the gentoo license string format
109 convertLicense :: Cabal.License -> String
110 convertLicense Cabal.GPL = "GPL-2" -- almost certainly version 2
111 convertLicense Cabal.LGPL = "LGPL-2.1" -- probably version 2.1
112 convertLicense Cabal.BSD3 = "BSD" -- do we really not
113 convertLicense Cabal.BSD4 = "BSD" -- distinguish between these?
114 convertLicense Cabal.PublicDomain = "public-domain"
115 convertLicense Cabal.AllRightsReserved = ""
116 convertLicense _ = ""
117
118 licenseComment Cabal.AllRightsReserved =
119 "Note: packages without a license cannot be included in portage"
120 licenseComment Cabal.OtherLicense =
121 "Fixme: \"OtherLicense\", please fill in manually"
122 licenseComment _ = ""
123
124 convertDependencies :: [Cabal.Dependency] -> [Dependency]
ace40ea Cope with IntersectVersionRanges, at least partially
Duncan Coutts authored
125 convertDependencies = concatMap convertDependency
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
126
ace40ea Cope with IntersectVersionRanges, at least partially
Duncan Coutts authored
127 convertDependency :: Cabal.Dependency -> [Dependency]
128 convertDependency (Cabal.Dependency name _)
129 | name `elem` coreLibs = [] -- no explicit dep on core libs
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
130 convertDependency (Cabal.Dependency name versionRange)
ace40ea Cope with IntersectVersionRanges, at least partially
Duncan Coutts authored
131 = case versionRange of
132 (Cabal.IntersectVersionRanges v1 v2) -> [convert v1, convert v2]
133 v -> [convert v]
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
134
135 where
136 ebuildName = "dev-haskell/" ++ map toLower name
9448bb7 @kolmodin Rewritten overlayonly functionality
kolmodin authored
137
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
138 convert :: Cabal.VersionRange -> Dependency
139 convert Cabal.AnyVersion = AnyVersionOf ebuildName
140 convert (Cabal.ThisVersion v) = ThisVersionOf (Cabal.showVersion v) ebuildName
141 convert (Cabal.LaterVersion v) = LaterVersionOf (Cabal.showVersion v) ebuildName
142 convert (Cabal.EarlierVersion v) = EarlierVersionOf (Cabal.showVersion v) ebuildName
143 convert (Cabal.UnionVersionRanges (Cabal.ThisVersion v1) (Cabal.LaterVersion v2))
144 | v1 == v2 = OrLaterVersionOf (Cabal.showVersion v1) ebuildName
145 convert (Cabal.UnionVersionRanges (Cabal.ThisVersion v1) (Cabal.EarlierVersion v2))
146 | v1 == v2 = OrEarlierVersionOf (Cabal.showVersion v1) ebuildName
147 convert (Cabal.UnionVersionRanges r1 r2)
148 = DependEither (convert r1) (convert r2)
149
5bcf377 Update hackport's ebuild generation to current conventions.
Duncan Coutts authored
150 coreLibs =
8022ddc Adding support for variable substitution in generated ebuilds
der_eq@freenet.de authored
151 ["rts"
152 ,"base"
153 ,"haskell98"
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
154 ,"template-haskell"
04db8bc Updatre HackPort's list of core libs
Duncan Coutts authored
155 ,"ghc"
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
156 ,"unix"
157 ,"parsec"
158 ,"stm"
7d56d4f Remove regex-* from list of core packages since they're upgradable
Duncan Coutts authored
159 ,"readline"]
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
160
161 showEBuild :: EBuild -> String
162 showEBuild ebuild =
5bcf377 Update hackport's ebuild generation to current conventions.
Duncan Coutts authored
163 ss "# Copyright 1999-2007 Gentoo Foundation". nl.
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
164 ss "# Distributed under the terms of the GNU General Public License v2". nl.
165 ss "# $Header: $". nl.
166 nl.
167 ss "CABAL_FEATURES=". quote' (sepBy " " $ features ebuild). nl.
168 ss "inherit haskell-cabal". nl.
169 nl.
20179c4 Set S= properly for packages with upper case names
Duncan Coutts authored
170 (case my_pn ebuild of
171 Nothing -> id
172 Just pn -> ss "MY_PN=". quote pn. nl.
173 ss "MY_P=". quote "${MY_PN}-${PV}". nl. nl).
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
174 ss "DESCRIPTION=". quote (description ebuild). nl.
175 ss "HOMEPAGE=". quote (homepage ebuild). nl.
8022ddc Adding support for variable substitution in generated ebuilds
der_eq@freenet.de authored
176 ss "SRC_URI=". quote (replaceVars (src_uri ebuild)).
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
177 (if null (src_uri ebuild) then ss "\t#Fixme: please fill in manually"
178 else id). nl.
5bcf377 Update hackport's ebuild generation to current conventions.
Duncan Coutts authored
179 nl.
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
180 ss "LICENSE=". quote (license ebuild).
181 (if null (licenseComments ebuild) then id
182 else ss "\t#". ss (licenseComments ebuild)). nl.
183 ss "SLOT=". quote (slot ebuild). nl.
63b57b8 Adapted HackPort to the new Hackage interface
der_eq@freenet.de authored
184 ss "KEYWORDS=". quote' (sepBy " " $ keywords ebuild).nl.
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
185 ss "IUSE=". quote' (sepBy ", " $ iuse ebuild). nl.
186 nl.
187 ss "DEPEND=". quote' (sepBy "\n\t\t" $ map showDepend $ depend ebuild). nl.
20179c4 Set S= properly for packages with upper case names
Duncan Coutts authored
188 (case my_pn ebuild of
189 Nothing -> id
2d0448c Oops, fix last nl patch.
Duncan Coutts authored
190 Just pn -> nl. ss "S=". quote ("${WORKDIR}/${MY_P}"). nl)
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
191 $ []
8022ddc Adding support for variable substitution in generated ebuilds
der_eq@freenet.de authored
192 where replaceVars = replaceCommonVars (name ebuild) (my_pn ebuild) (version ebuild)
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
193
194 showDepend (AnyVersionOf package) = package
3754021 == cabal deps correspond to ~ portage deps
Duncan Coutts authored
195 showDepend (ThisVersionOf version package) = "~" ++ package ++ "-" ++ version
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
196 showDepend (LaterVersionOf version package) = ">" ++ package ++ "-" ++ version
197 showDepend (EarlierVersionOf version package) = "<" ++ package ++ "-" ++ version
198 showDepend (OrLaterVersionOf version package) = ">=" ++ package ++ "-" ++ version
199 showDepend (OrEarlierVersionOf version package) = "<=" ++ package ++ "-" ++ version
200 showDepend (DependEither depend1 depend2) = showDepend depend1
201 ++ " || " ++ showDepend depend2
202 showDepend (DependIfUse useflag depend@(DependEither _ _))
203 = useflag ++ "? " ++ showDepend depend
204 showDepend (DependIfUse useflag depend) = useflag ++ "? ( " ++ showDepend depend ++ " )"
205
206 ss = showString
207 sc = showChar
208 nl = sc '\n'
209
210 quote str = sc '"'. ss str. sc '"'
211 quote' str = sc '"'. str. sc '"'
212
213 sepBy :: String -> [String] -> ShowS
214 sepBy s [] = id
215 sepBy s [x] = ss x
216 sepBy s (x:xs) = ss x. ss s. sepBy s xs
8022ddc Adding support for variable substitution in generated ebuilds
der_eq@freenet.de authored
217
218 getRestIfPrefix ::
219 String -> -- ^ the prefix
220 String -> -- ^ the string
221 Maybe String
222 getRestIfPrefix (p:ps) (x:xs) = if p==x then getRestIfPrefix ps xs else Nothing
223 getRestIfPrefix [] rest = Just rest
224 getRestIfPrefix _ [] = Nothing
225
226 subStr ::
227 String -> -- ^ the search string
228 String -> -- ^ the string to be searched
9448bb7 @kolmodin Rewritten overlayonly functionality
kolmodin authored
229 Maybe (String,String) -- ^ Just (pre,post) if string is found
8022ddc Adding support for variable substitution in generated ebuilds
der_eq@freenet.de authored
230 subStr sstr str = case getRestIfPrefix sstr str of
231 Nothing -> if null str then Nothing else case subStr sstr (tail str) of
232 Nothing -> Nothing
233 Just (pre,post) -> Just (head str:pre,post)
234 Just rest -> Just ([],rest)
235
236 replaceMultiVars ::
237 [(String,String)] -> -- ^ pairs of variable name and content
238 String -> -- ^ string to be searched
239 String -- ^ the result
240 replaceMultiVars [] str = str
241 replaceMultiVars whole@((name,cont):rest) str = case subStr cont str of
242 Nothing -> replaceMultiVars rest str
243 Just (pre,post) -> (replaceMultiVars rest pre)++name++(replaceMultiVars whole post)
244
245 replaceCommonVars ::
246 String -> -- ^ PN
247 Maybe String -> -- ^ MYPN
248 String -> -- ^ PV
249 String -> -- ^ the string to be replaced
250 String
251 replaceCommonVars pn mypn pv str
252 = replaceMultiVars
253 ([("${P}",pn++"-"++pv)]
254 ++ maybe [] (\x->[("${MY_P}",x++"-"++pv)]) mypn
255 ++[("${PN}",pn)]
256 ++ maybe [] (\x->[("${MY_PN}",x)]) mypn
257 ++[("${PV}",pv)]) str
Something went wrong with that request. Please try again.