Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 257 lines (233 sloc) 9.895 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]
125 convertDependencies = catMaybes . map convertDependency
126
127 convertDependency :: Cabal.Dependency -> Maybe Dependency
128 convertDependency (Cabal.Dependency name versionRange)
5bcf377 Update hackport's ebuild generation to current conventions.
Duncan Coutts authored
129 | name `elem` coreLibs = Nothing -- no explicit dep on core libs
130 | otherwise = Just $ convert versionRange
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
131
132 where
133 ebuildName = "dev-haskell/" ++ map toLower name
134
135 convert :: Cabal.VersionRange -> Dependency
136 convert Cabal.AnyVersion = AnyVersionOf ebuildName
137 convert (Cabal.ThisVersion v) = ThisVersionOf (Cabal.showVersion v) ebuildName
138 convert (Cabal.LaterVersion v) = LaterVersionOf (Cabal.showVersion v) ebuildName
139 convert (Cabal.EarlierVersion v) = EarlierVersionOf (Cabal.showVersion v) ebuildName
140 convert (Cabal.UnionVersionRanges (Cabal.ThisVersion v1) (Cabal.LaterVersion v2))
141 | v1 == v2 = OrLaterVersionOf (Cabal.showVersion v1) ebuildName
142 convert (Cabal.UnionVersionRanges (Cabal.ThisVersion v1) (Cabal.EarlierVersion v2))
143 | v1 == v2 = OrEarlierVersionOf (Cabal.showVersion v1) ebuildName
144 convert (Cabal.UnionVersionRanges r1 r2)
145 = DependEither (convert r1) (convert r2)
146 -- convert (Cabal.IntersectVersionRanges r1 r2)
147 -- = convert r1 ++ "&&" ++ convert r2
148
5bcf377 Update hackport's ebuild generation to current conventions.
Duncan Coutts authored
149 coreLibs =
8022ddc Adding support for variable substitution in generated ebuilds
der_eq@freenet.de authored
150 ["rts"
151 ,"base"
152 ,"haskell98"
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
153 ,"template-haskell"
04db8bc Updatre HackPort's list of core libs
Duncan Coutts authored
154 ,"ghc"
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
155 ,"unix"
156 ,"parsec"
157 ,"stm"
7d56d4f Remove regex-* from list of core packages since they're upgradable
Duncan Coutts authored
158 ,"readline"]
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
159
160 showEBuild :: EBuild -> String
161 showEBuild ebuild =
5bcf377 Update hackport's ebuild generation to current conventions.
Duncan Coutts authored
162 ss "# Copyright 1999-2007 Gentoo Foundation". nl.
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
163 ss "# Distributed under the terms of the GNU General Public License v2". nl.
164 ss "# $Header: $". nl.
165 nl.
166 ss "CABAL_FEATURES=". quote' (sepBy " " $ features ebuild). nl.
167 ss "inherit haskell-cabal". nl.
168 nl.
20179c4 Set S= properly for packages with upper case names
Duncan Coutts authored
169 (case my_pn ebuild of
170 Nothing -> id
171 Just pn -> ss "MY_PN=". quote pn. nl.
172 ss "MY_P=". quote "${MY_PN}-${PV}". nl. nl).
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
173 ss "DESCRIPTION=". quote (description ebuild). nl.
174 ss "HOMEPAGE=". quote (homepage ebuild). nl.
8022ddc Adding support for variable substitution in generated ebuilds
der_eq@freenet.de authored
175 ss "SRC_URI=". quote (replaceVars (src_uri ebuild)).
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
176 (if null (src_uri ebuild) then ss "\t#Fixme: please fill in manually"
177 else id). nl.
5bcf377 Update hackport's ebuild generation to current conventions.
Duncan Coutts authored
178 nl.
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
179 ss "LICENSE=". quote (license ebuild).
180 (if null (licenseComments ebuild) then id
181 else ss "\t#". ss (licenseComments ebuild)). nl.
182 ss "SLOT=". quote (slot ebuild). nl.
63b57b8 Adapted HackPort to the new Hackage interface
der_eq@freenet.de authored
183 ss "KEYWORDS=". quote' (sepBy " " $ keywords ebuild).nl.
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
184 ss "IUSE=". quote' (sepBy ", " $ iuse ebuild). nl.
185 nl.
186 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
187 (case my_pn ebuild of
188 Nothing -> id
189 Just pn -> nl. ss "S=". quote ("${WORKDIR}/${MY_P}"))
aff37c2 First release of HackPort, the Hackage tool for Portage
der_eq@freenet.de authored
190 $ []
8022ddc Adding support for variable substitution in generated ebuilds
der_eq@freenet.de authored
191 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
192
193 showDepend (AnyVersionOf package) = package
194 showDepend (ThisVersionOf version package) = "=" ++ package ++ "-" ++ version
195 showDepend (LaterVersionOf version package) = ">" ++ package ++ "-" ++ version
196 showDepend (EarlierVersionOf version package) = "<" ++ package ++ "-" ++ version
197 showDepend (OrLaterVersionOf version package) = ">=" ++ package ++ "-" ++ version
198 showDepend (OrEarlierVersionOf version package) = "<=" ++ package ++ "-" ++ version
199 showDepend (DependEither depend1 depend2) = showDepend depend1
200 ++ " || " ++ showDepend depend2
201 showDepend (DependIfUse useflag depend@(DependEither _ _))
202 = useflag ++ "? " ++ showDepend depend
203 showDepend (DependIfUse useflag depend) = useflag ++ "? ( " ++ showDepend depend ++ " )"
204
205 ss = showString
206 sc = showChar
207 nl = sc '\n'
208
209 quote str = sc '"'. ss str. sc '"'
210 quote' str = sc '"'. str. sc '"'
211
212 sepBy :: String -> [String] -> ShowS
213 sepBy s [] = id
214 sepBy s [x] = ss x
215 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
216
217 getRestIfPrefix ::
218 String -> -- ^ the prefix
219 String -> -- ^ the string
220 Maybe String
221 getRestIfPrefix (p:ps) (x:xs) = if p==x then getRestIfPrefix ps xs else Nothing
222 getRestIfPrefix [] rest = Just rest
223 getRestIfPrefix _ [] = Nothing
224
225 subStr ::
226 String -> -- ^ the search string
227 String -> -- ^ the string to be searched
228 Maybe (String,String) -- ^ Just (pre,post) if string is found
229 subStr sstr str = case getRestIfPrefix sstr str of
230 Nothing -> if null str then Nothing else case subStr sstr (tail str) of
231 Nothing -> Nothing
232 Just (pre,post) -> Just (head str:pre,post)
233 Just rest -> Just ([],rest)
234
235 replaceMultiVars ::
236 [(String,String)] -> -- ^ pairs of variable name and content
237 String -> -- ^ string to be searched
238 String -- ^ the result
239 replaceMultiVars [] str = str
240 replaceMultiVars whole@((name,cont):rest) str = case subStr cont str of
241 Nothing -> replaceMultiVars rest str
242 Just (pre,post) -> (replaceMultiVars rest pre)++name++(replaceMultiVars whole post)
243
244 replaceCommonVars ::
245 String -> -- ^ PN
246 Maybe String -> -- ^ MYPN
247 String -> -- ^ PV
248 String -> -- ^ the string to be replaced
249 String
250 replaceCommonVars pn mypn pv str
251 = replaceMultiVars
252 ([("${P}",pn++"-"++pv)]
253 ++ maybe [] (\x->[("${MY_P}",x++"-"++pv)]) mypn
254 ++[("${PN}",pn)]
255 ++ maybe [] (\x->[("${MY_PN}",x)]) mypn
256 ++[("${PV}",pv)]) str
Something went wrong with that request. Please try again.