summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennartKolmodin <>2010-06-29 14:16:20 (GMT)
committerLuite Stegeman <luite@luite.com>2010-06-29 14:16:20 (GMT)
commit0c9047b28b9350a4d74d490c5252d50d1fa9e5f4 (patch)
tree96df72a6fbcceaecee79b336af2f188c0a4d8551
parent1985899a588577277edfbf8ebf4168b2e3a0bb5a (diff)
version 0.2.70.2.7
-rw-r--r--Cabal2Ebuild.hs251
-rw-r--r--Main.hs7
-rw-r--r--Merge.hs181
-rw-r--r--Merge/Dependencies.hs259
-rw-r--r--Portage/Dependency.hs74
-rw-r--r--Portage/EBuild.hs174
-rw-r--r--Portage/PackageId.hs4
-rw-r--r--Portage/Version.hs9
-rw-r--r--hackport.cabal3
9 files changed, 552 insertions, 410 deletions
diff --git a/Cabal2Ebuild.hs b/Cabal2Ebuild.hs
index e8034de..cd697c9 100644
--- a/Cabal2Ebuild.hs
+++ b/Cabal2Ebuild.hs
@@ -22,11 +22,10 @@
-- cabal2ebuild - a program for generating a Gentoo ebuild from a .cabal file
--
module Cabal2Ebuild
- (EBuild(..)
- ,Dependency(..)
- ,cabal2ebuild
+ (cabal2ebuild
,convertDependencies
- ,showEBuild) where
+ ,convertDependency
+ ,default_ghc_dependency) where
import qualified Distribution.PackageDescription as Cabal
(PackageDescription(..))
@@ -35,134 +34,67 @@ import qualified Distribution.Package as Cabal (PackageIdentifier(..)
, PackageName(..))
import qualified Distribution.Version as Cabal (VersionRange, foldVersionRange', versionBranch, Version)
import qualified Distribution.License as Cabal (License(..))
-import qualified Distribution.Text as Cabal (display)
+import Distribution.Text (display)
import Data.Char (toLower,isUpper)
import Portage.Dependency
+import qualified Portage.PackageId as Portage
+import qualified Portage.EBuild as Portage
+import qualified Portage.EBuild as E
import Portage.Version
-data EBuild = EBuild {
- name :: String,
- version :: String,
- description :: String,
- homepage :: String,
- src_uri :: String,
- license :: String,
- slot :: String,
- keywords :: [String],
- iuse :: [String],
- haskell_deps :: [Dependency],
- build_tools :: [Dependency],
- extra_libs :: [Dependency],
- cabal_dep :: Dependency,
- ghc_dep :: Dependency,
- depend :: [String],
- rdepend :: [String],
- features :: [String],
- -- comments on various fields for communicating stuff to the user
- licenseComments :: String,
- my_pn :: Maybe String --If the package's name contains upper-case
- }
+default_ghc_dependency :: Dependency
+default_ghc_dependency = OrLaterVersionOf (Version [6,8,1] Nothing [] 0) (Portage.mkPackageName "dev-lang" "ghc")
-ebuildTemplate :: EBuild
-ebuildTemplate = EBuild {
- name = "foobar",
- version = "0.1",
- description = "",
- homepage = "",
- src_uri = "",
- license = "",
- slot = "0",
- keywords = ["~amd64","~x86"],
- iuse = [],
- haskell_deps = [],
- build_tools = [],
- extra_libs = [],
- cabal_dep = AnyVersionOf "dev-haskell/cabal",
- ghc_dep = defaultDepGHC,
- depend = [],
- rdepend = [],
- features = [],
- licenseComments = "",
- my_pn = Nothing
- }
-
-cabal2ebuild :: Cabal.PackageDescription -> EBuild
-cabal2ebuild pkg = ebuildTemplate {
- name = map toLower cabalPkgName,
- version = Cabal.display (Cabal.pkgVersion (Cabal.package pkg)),
- description = if null (Cabal.synopsis pkg) then Cabal.description pkg
+cabal2ebuild :: Cabal.PackageDescription -> Portage.EBuild
+cabal2ebuild pkg = Portage.ebuildTemplate {
+ E.name = map toLower cabalPkgName,
+ E.version = display (Cabal.pkgVersion (Cabal.package pkg)),
+ E.description = if null (Cabal.synopsis pkg) then Cabal.description pkg
else Cabal.synopsis pkg,
- homepage = Cabal.homepage pkg,
- src_uri = Cabal.pkgUrl pkg,
- license = convertLicense (Cabal.license pkg),
- licenseComments = licenseComment (Cabal.license pkg),
- haskell_deps = simplify_deps $ convertDependencies (Cabal.buildDepends pkg),
- cabal_dep = head $ convertDependency (Cabal.Dependency (Cabal.PackageName "Cabal")
- (Cabal.descCabalVersion pkg)),
- my_pn = if any isUpper cabalPkgName then Just cabalPkgName else Nothing,
- features = features ebuildTemplate
+ E.homepage = Cabal.homepage pkg,
+ E.src_uri = Cabal.pkgUrl pkg,
+ E.license = Cabal.license pkg,
+ E.my_pn = if any isUpper cabalPkgName then Just cabalPkgName else Nothing,
+ E.features = E.features E.ebuildTemplate
++ (if hasExe then ["bin"] else [])
++ maybe [] (const (["lib","profile","haddock"]
++ if cabalPkgName == "hscolour" then [] else ["hscolour"])
) (Cabal.library pkg) -- hscolour can't colour its own sources
} where
- cabalPkgName = Cabal.display $ Cabal.pkgName (Cabal.package pkg)
- -- hasLib = isJust (Cabal.library pkg)
+ cabalPkgName = display $ Cabal.pkgName (Cabal.package pkg)
hasExe = (not . null) (Cabal.executables pkg)
-defaultDepGHC :: Dependency
-defaultDepGHC = OrLaterVersionOf (Version [6,8,1] Nothing [] 0) "dev-lang/ghc"
-
--- map the cabal license type to the gentoo license string format
-convertLicense :: Cabal.License -> String
-convertLicense (Cabal.GPL mv) = "GPL-" ++ (maybe "2" Cabal.display mv) -- almost certainly version 2
-convertLicense (Cabal.LGPL mv) = "LGPL-" ++ (maybe "2.1" Cabal.display mv) -- probably version 2.1
-convertLicense Cabal.BSD3 = "BSD"
-convertLicense Cabal.BSD4 = "BSD-4"
-convertLicense Cabal.PublicDomain = "public-domain"
-convertLicense Cabal.AllRightsReserved = ""
-convertLicense Cabal.MIT = "MIT"
-convertLicense _ = ""
-
-licenseComment :: Cabal.License -> String
-licenseComment Cabal.AllRightsReserved =
- "Note: packages without a license cannot be included in portage"
-licenseComment Cabal.OtherLicense =
- "Fixme: \"OtherLicense\", please fill in manually"
-licenseComment _ = ""
-
-convertDependencies :: [Cabal.Dependency] -> [Dependency]
-convertDependencies = concatMap convertDependency
+convertDependencies :: Portage.Category -> [Cabal.Dependency] -> [Dependency]
+convertDependencies category = concatMap (convertDependency category)
-convertDependency :: Cabal.Dependency -> [Dependency]
-convertDependency (Cabal.Dependency pname@(Cabal.PackageName _name) _)
+convertDependency :: Portage.Category -> Cabal.Dependency -> [Dependency]
+convertDependency _category (Cabal.Dependency pname@(Cabal.PackageName _name) _)
| pname `elem` coreLibs = [] -- no explicit dep on core libs
-convertDependency (Cabal.Dependency pname versionRange)
+convertDependency category (Cabal.Dependency pname versionRange)
= convert versionRange
where
-- XXX: not always true, we should look properly for deps in the overlay
-- to find the correct category
- ebuildName = "dev-haskell/" ++ map toLower (Cabal.display pname)
+ pn = Portage.PackageName category (Portage.normalizeCabalPackageName pname)
convert :: Cabal.VersionRange -> [Dependency]
convert = Cabal.foldVersionRange'
- ( [AnyVersionOf ebuildName] -- ^ @\"-any\"@ version
- )(\v -> [ThisVersionOf (cabalVtoHPv v) ebuildName] -- ^ @\"== v\"@
- )(\v -> [LaterVersionOf (cabalVtoHPv v) ebuildName] -- ^ @\"> v\"@
- )(\v -> [EarlierVersionOf (cabalVtoHPv v) ebuildName] -- ^ @\"< v\"@
- )(\v -> [OrLaterVersionOf (cabalVtoHPv v) ebuildName] -- ^ @\">= v\"@
- )(\v -> [OrEarlierVersionOf (cabalVtoHPv v) ebuildName] -- ^ @\"<= v\"@
-{- FIXME -} )(\v1 _ -> [ThisMajorOf (cabalVtoHPv v1) ebuildName] -- ^ @\"== v.*\"@ wildcard. (incl lower, excl upper)
- )(\r1 r2 -> case (r1,r2) of
- ([r1'], [r2']) -> [DependEither r1' r2'] -- ^ @\"_ || _\"@ union
- _ -> error "convertDependency: compound either"
+ ( [AnyVersionOf pn] -- ^ @\"-any\"@ version
+ )(\v -> [ThisVersionOf (fromCabalVersion v) pn] -- ^ @\"== v\"@
+ )(\v -> [LaterVersionOf (fromCabalVersion v) pn] -- ^ @\"> v\"@
+ )(\v -> [EarlierVersionOf (fromCabalVersion v) pn] -- ^ @\"< v\"@
+ )(\v -> [OrLaterVersionOf (fromCabalVersion v) pn] -- ^ @\">= v\"@
+ )(\v -> [OrEarlierVersionOf (fromCabalVersion v) pn] -- ^ @\"<= v\"@
+ )(\v _ -> [ThisMajorOf (fromCabalVersion v) pn] -- ^ @\"== v.*\"@ wildcard. (incl lower, excl upper)
+ )(\g1 g2 -> [DependEither (flatten g1 ++ flatten g2) ] -- ^ @\"_ || _\"@ union
)(\r1 r2 -> r1 ++ r2
)
+ where
+ flatten :: [Dependency] -> [[Dependency]]
+ flatten [DependEither ds] = concatMap flatten ds
+ flatten other = [other]
--- converts Cabal version type to hackport version
-cabalVtoHPv :: Cabal.Version -> Version
-cabalVtoHPv = (\v -> Version v Nothing [] 0) . Cabal.versionBranch
coreLibs :: [Cabal.PackageName]
coreLibs = map Cabal.PackageName
@@ -191,110 +123,3 @@ coreLibs = map Cabal.PackageName
,"template-haskell"
,"unix" --has ebuild, but only in the overlay
]
-
-showEBuild :: EBuild -> String
-showEBuild ebuild =
- ss "# Copyright 1999-2010 Gentoo Foundation". nl.
- ss "# Distributed under the terms of the GNU General Public License v2". nl.
- ss "# $Header: $". nl.
- nl.
- ss "CABAL_FEATURES=". quote' (sepBy " " $ features ebuild). nl.
- ss "inherit haskell-cabal". nl.
- nl.
- (case my_pn ebuild of
- Nothing -> id
- Just pn -> ss "MY_PN=". quote pn. nl.
- ss "MY_P=". quote "${MY_PN}-${PV}". nl. nl).
- ss "DESCRIPTION=". quote (description ebuild). nl.
- ss "HOMEPAGE=". quote (homepage ebuild). nl.
- ss "SRC_URI=". quote (replaceVars (src_uri ebuild)).
- (if null (src_uri ebuild) then ss "\t#Fixme: please fill in manually"
- else id). nl.
- nl.
- ss "LICENSE=". quote (license ebuild).
- (if null (licenseComments ebuild) then id
- else ss "\t#". ss (licenseComments ebuild)). nl.
- ss "SLOT=". quote (slot ebuild). nl.
- ss "KEYWORDS=". quote' (sepBy " " $ keywords ebuild).nl.
- ss "IUSE=". quote' (sepBy ", " $ iuse ebuild). nl.
- nl.
- ( if (not . null . build_tools $ ebuild)
- then ss "BUILDTOOLS=". quote' (sepBy "\n\t\t" $ map showDepend $ build_tools ebuild). nl
- else id
- ).
- ( if (not . null . extra_libs $ ebuild )
- then ss "EXTRALIBS=". quote' (sepBy "\n\t\t" $ map showDepend $ extra_libs ebuild). nl
- else id
- ).
- ( if (not . null . haskell_deps $ ebuild)
- then ss "HASKELLDEPS=". quote' (sepBy "\n\t\t" $ map showDepend $ haskell_deps ebuild). nl
- else id
- ).
- ss "RDEPEND=". quote' (sepBy "\n\t\t" $ rdepend ebuild). nl.
- ss "DEPEND=". quote' (sepBy "\n\t\t" $ depend ebuild). nl.
- (case my_pn ebuild of
- Nothing -> id
- Just _ -> nl. ss "S=". quote ("${WORKDIR}/${MY_P}"). nl)
- $ []
- where replaceVars = replaceCommonVars (name ebuild) (my_pn ebuild) (version ebuild)
-
-ss :: String -> String -> String
-ss = showString
-
-sc :: Char -> String -> String
-sc = showChar
-
-nl :: String -> String
-nl = sc '\n'
-
-quote :: String -> String -> String
-quote str = sc '"'. ss str. sc '"'
-
-quote' :: (String -> String) -> String -> String
-quote' str = sc '"'. str. sc '"'
-
-sepBy :: String -> [String] -> ShowS
-sepBy _ [] = id
-sepBy _ [x] = ss x
-sepBy s (x:xs) = ss x. ss s. sepBy s xs
-
-getRestIfPrefix ::
- String -> -- ^ the prefix
- String -> -- ^ the string
- Maybe String
-getRestIfPrefix (p:ps) (x:xs) = if p==x then getRestIfPrefix ps xs else Nothing
-getRestIfPrefix [] rest = Just rest
-getRestIfPrefix _ [] = Nothing
-
-subStr ::
- String -> -- ^ the search string
- String -> -- ^ the string to be searched
- Maybe (String,String) -- ^ Just (pre,post) if string is found
-subStr sstr str = case getRestIfPrefix sstr str of
- Nothing -> if null str then Nothing else case subStr sstr (tail str) of
- Nothing -> Nothing
- Just (pre,post) -> Just (head str:pre,post)
- Just rest -> Just ([],rest)
-
-replaceMultiVars ::
- [(String,String)] -> -- ^ pairs of variable name and content
- String -> -- ^ string to be searched
- String -- ^ the result
-replaceMultiVars [] str = str
-replaceMultiVars whole@((pname,cont):rest) str = case subStr cont str of
- Nothing -> replaceMultiVars rest str
- Just (pre,post) -> (replaceMultiVars rest pre)++pname++(replaceMultiVars whole post)
-
-replaceCommonVars ::
- String -> -- ^ PN
- Maybe String -> -- ^ MYPN
- String -> -- ^ PV
- String -> -- ^ the string to be replaced
- String
-replaceCommonVars pn mypn pv str
- = replaceMultiVars
- ([("${P}",pn++"-"++pv)]
- ++ maybe [] (\x->[("${MY_P}",x++"-"++pv)]) mypn
- ++[("${PN}",pn)]
- ++ maybe [] (\x->[("${MY_PN}",x)]) mypn
- ++[("${PV}",pv)]) str
diff --git a/Main.hs b/Main.hs
index 7064a92..0a77907 100644
--- a/Main.hs
+++ b/Main.hs
@@ -40,7 +40,8 @@ import System.Directory ( doesDirectoryExist )
import System.Exit ( exitFailure )
import System.FilePath ( (</>) )
-import qualified Cabal2Ebuild as E
+import qualified Cabal2Ebuild as C2E
+import qualified Portage.EBuild as E
import Diff
import Error
@@ -150,9 +151,9 @@ makeEbuildAction flags args _globalFlags = do
let _verbosity = fromFlag (makeEbuildVerbosity flags)
forM_ args $ \cabalFileName -> do
pkg <- Cabal.readPackageDescription normal cabalFileName
- let ebuild = E.cabal2ebuild (flattenPackageDescription pkg)
+ let ebuild = C2E.cabal2ebuild (flattenPackageDescription pkg)
let ebuildFileName = E.name ebuild ++ "-" ++ E.version ebuild ++ ".ebuild"
- writeFile ebuildFileName (E.showEBuild ebuild)
+ writeFile ebuildFileName (display ebuild)
makeEbuildCommand :: CommandUI MakeEbuildFlags
makeEbuildCommand = CommandUI {
diff --git a/Merge.hs b/Merge.hs
index 3448e16..ccb3419 100644
--- a/Merge.hs
+++ b/Merge.hs
@@ -1,42 +1,4 @@
{-# OPTIONS -XPatternGuards #-}
-{- | Merge a package from hackage to an ebuild.
-
-Merging a library
-=================
-
-Compile time:
- ghc
- cabal
- build tools
- deps (haskell dependencies)
- extra-libs (c-libs)
-
-Run time:
- ghc
- deps (haskell dependencies)
- extra-libs (c-libs)
-
-RDEPEND="ghc ${DEPS} ${EXTRALIBS}"
-DEPEND="${RDEPEND} cabal ${BUILDTOOLS}"
-
-Merging an executable
-=====================
-Packages with both executable and library must be treated as libraries, as it will impose a stricter DEPEND.
-
-Compile time:
- ghc
- cabal
- build tools
- deps
- extra-libs (c-libs)
-
-Run time:
- extra-libs (c-libs)
-
-RDEPEND="${EXTRALIBS}"
-DEPEND="${RDEPEND} ghc cabal ${DEPS} ${BUILDTOOLS}"
-
--}
module Merge
( merge ) where
@@ -48,12 +10,7 @@ import Distribution.Package
import Distribution.Compiler (CompilerId(..), CompilerFlavor(GHC))
import Distribution.PackageDescription ( PackageDescription(..)
, FlagName(..)
- , libBuildInfo
- , buildInfo
- , buildable
- , extraLibs
- , buildTools
- , hasLibs )
+ )
import Distribution.PackageDescription.Configuration
( finalizePackageDescription )
import Distribution.Text (display)
@@ -65,8 +22,8 @@ import System.Directory ( getCurrentDirectory
import System.Cmd (system)
import System.FilePath ((</>))
-import qualified Cabal2Ebuild as E
-import Cabal2Ebuild
+import qualified Cabal2Ebuild as C2E
+import qualified Portage.EBuild as E
import Error as E
import qualified Distribution.Package as Cabal
@@ -85,11 +42,12 @@ import Distribution.Client.Types
import qualified Portage.PackageId as Portage
import qualified Portage.Version as Portage
-import qualified Portage.Dependency as Portage
import qualified Portage.Host as Host
import qualified Portage.Overlay as Overlay
import qualified Portage.Resolve as Portage
+import qualified Merge.Dependencies as Merge
+
import Debug.Trace ( trace )
(<->) :: String -> String -> String
@@ -154,8 +112,8 @@ merge verbosity repo serverURI args overlayPath = do
let (Cabal.PackageName user_pname_str) = user_pName
overlay <- Overlay.loadLazy overlayPath
- portage_path <- Host.portage_dir `fmap` Host.getInfo
- portage <- Overlay.loadLazy portage_path
+ -- portage_path <- Host.portage_dir `fmap` Host.getInfo
+ -- portage <- Overlay.loadLazy portage_path
index <- fmap packageIndex $ getAvailablePackages verbosity [ repo ]
-- find all packages that maches the user specified package name
@@ -185,7 +143,7 @@ merge verbosity repo serverURI args overlayPath = do
let cabal_pkgId = packageInfoId selectedPkg
norm_pkgId = Portage.normalizeCabalPackageId cabal_pkgId
norm_pkgName = packageName norm_pkgId
- cat <- Portage.resolveCategory verbosity overlay norm_pkgName
+ cat <- maybe (Portage.resolveCategory verbosity overlay norm_pkgName) return m_category
let pkgGenericDesc = packageDescription selectedPkg
Right (pkgDesc0, flags) =
@@ -203,59 +161,17 @@ merge verbosity repo serverURI args overlayPath = do
| Dependency pn vr <- buildDepends pkgDesc0
]
in pkgDesc0 { buildDepends = deps }
+ edeps = Merge.resolveDependencies pkgDesc
- hasBuildableExes p =
- any (buildable . buildInfo)
- . executables $ p
- treatAsLibrary = (not . hasBuildableExes) pkgDesc && hasLibs pkgDesc
-
- -- calculate build tools
- bt = [ pkg' -- TODO: currently ignoring version range
- | Cabal.Dependency (Cabal.PackageName pkg ) _range <- buildToolsDeps pkgDesc
- , Just pkg' <- return (lookup pkg buildToolsTable)
- ]
-
- packageNameResolver s = do
- (Portage.PackageName (Portage.Category p_cat) (Cabal.PackageName pn))
- <- Portage.resolveFullPortageName portage (Cabal.PackageName s)
- return $ E.AnyVersionOf (p_cat </> pn)
-
- -- calculate extra-libs
- extra <- findCLibs verbosity packageNameResolver pkgDesc
-
debug verbosity ("Selected flags: " ++ show flags)
- debug verbosity ("extra-libs: ")
- mapM_ (debug verbosity . show) extra
-
- debug verbosity ("build-tools:")
- mapM_ (debug verbosity . show) bt
-
- -- debug verbosity ("Finalized package:\n" ++ showPackageDescription pkgDesc)
-
- -- TODO: more fixes
- -- * inherit keywords from previous ebuilds
- let d e = if treatAsLibrary
- then Portage.showDepend (cabal_dep e)
- : "${RDEPEND}"
- : [ "${BUILDTOOLS}" | not . null $ build_tools e ]
- else Portage.showDepend (cabal_dep e)
- : Portage.showDepend (ghc_dep e)
- : "${RDEPEND}"
- : [ "${BUILDTOOLS}" | not . null $ build_tools e ]
- ++ [ "${HASKELLDEPS}" | not . null $ haskell_deps e ]
- rd e = if treatAsLibrary
- then Portage.showDepend (ghc_dep e)
- : [ "${HASKELLDEPS}" | not . null $ haskell_deps e ]
- ++ [ "${EXTRALIBS}" | not . null $ extra_libs e ]
- else [ "${EXTRALIBS}" | not . null $ extra_libs e ]
+
let ebuild = fixSrc serverURI (packageId pkgDesc)
- . (\e -> e { depend = d e } )
- . (\e -> e { rdepend = rd e } )
- . (\e -> e { extra_libs = extra_libs e ++ extra } )
- . (\e -> e { build_tools = build_tools e ++ bt } )
- $ E.cabal2ebuild pkgDesc
+ . (\e -> e { E.depend = Merge.dep edeps } )
+ . (\e -> e { E.depend_extra = Merge.dep_e edeps } )
+ . (\e -> e { E.rdepend = Merge.rdep edeps } )
+ . (\e -> e { E.rdepend_extra = Merge.rdep_e edeps } )
+ $ C2E.cabal2ebuild pkgDesc
- debug verbosity ("Treat as library: " ++ show treatAsLibrary)
mergeEbuild verbosity overlayPath (Portage.unCategory cat) ebuild
fetchAndDigest
verbosity
@@ -263,57 +179,6 @@ merge verbosity repo serverURI args overlayPath = do
(display cabal_pkgId <.> "tar.gz")
(mkUri cabal_pkgId)
-findCLibs :: Verbosity -> (String -> Maybe E.Dependency) -> PackageDescription -> IO [E.Dependency]
-findCLibs verbosity portageResolver (PackageDescription { library = lib, executables = exes }) = do
- debug verbosity "Mapping extra-libraries into portage packages..."
- -- for extra libs we don't find, maybe look into into installed packages?
- when (not . null $ notFound) $
- warn verbosity ("Could not find portage packages for extra-libraries: " ++ unwords notFound)
- when (not . null $ found) $
- debug verbosity ("Found c-libraries deps: " ++ show found)
- return found
- where
- resolvers = [ staticTranslateExtraLib, portageResolver ]
-
- resolved = [ chain p resolvers
- | p <- libE ++ exeE
- ] :: [Either String E.Dependency]
-
- notFound = [ p | Left p <- resolved ]
- found = [ p | Right p <- resolved ]
-
- chain v [] = Left v
- chain v (f:fs) = case f v of
- Nothing -> chain v fs
- Just x -> Right x
-
- libE = maybe [] (extraLibs.libBuildInfo) lib
- exeE = concatMap (extraLibs.buildInfo) exes
-
-staticTranslateExtraLib :: String -> Maybe E.Dependency
-staticTranslateExtraLib lib = lookup lib m
- where
- m = [ ("z", E.AnyVersionOf "sys-libs/zlib")
- , ("bz2", E.AnyVersionOf "sys-libs/bzlib")
- , ("mysqlclient", E.LaterVersionOf (Portage.Version [4,0] Nothing [] 0) "virtual/mysql")
- , ("pq", E.LaterVersionOf (Portage.Version [7] Nothing [] 0) "virtual/postgresql-base")
- , ("ev", E.AnyVersionOf "dev-libs/libev")
- ]
-
-buildToolsDeps :: PackageDescription -> [Cabal.Dependency]
-buildToolsDeps (PackageDescription { library = lib, executables = exes }) = cabalDeps
- where
- cabalDeps = depL ++ depE
- depL = maybe [] (buildTools.libBuildInfo) lib
- depE = concatMap (buildTools.buildInfo) exes
-
-buildToolsTable :: [(String, E.Dependency)]
-buildToolsTable =
- [ ("happy", E.AnyVersionOf "dev-haskell/happy")
- , ("alex", E.AnyVersionOf "dev-haskell/alex")
- , ("c2hs", E.AnyVersionOf "dev-haskell/c2hs")
- ]
-
mkUri :: Cabal.PackageIdentifier -> URI
mkUri pid =
-- example:
@@ -335,7 +200,7 @@ fetchAndDigest verbosity ebuildDir tarballName tarballURI =
repo_info <- Host.getInfo
let tarDestination = (Host.distfiles_dir repo_info) </> tarballName
downloadURI verbosity tarballURI tarDestination
- -- Just err -> throwEx (E.DownloadFailed (show tarballURI) (show err))
+ -- Just err -> throwEx (Portage.DownloadFailed (show tarballURI) (show err))
-- TODO: downloadURI will throw a non-hackport exception if the
-- download fails
notice verbosity $ "Saved to " ++ tarDestination
@@ -351,19 +216,19 @@ withWorkingDirectory newDir action = do
(\_ -> setCurrentDirectory oldDir)
(\_ -> action)
-mergeEbuild :: Verbosity -> FilePath -> String -> EBuild -> IO ()
+mergeEbuild :: Verbosity -> FilePath -> String -> E.EBuild -> IO ()
mergeEbuild verbosity target cat ebuild = do
- let edir = target </> cat </> name ebuild
- elocal = name ebuild ++"-"++ version ebuild <.> "ebuild"
+ let edir = target </> cat </> E.name ebuild
+ elocal = E.name ebuild ++"-"++ E.version ebuild <.> "ebuild"
epath = edir </> elocal
createDirectoryIfMissing True edir
info verbosity $ "Writing " ++ elocal
- writeFile epath (showEBuild ebuild)
+ writeFile epath (display ebuild)
-fixSrc :: URI -> PackageIdentifier -> EBuild -> EBuild
+fixSrc :: URI -> PackageIdentifier -> E.EBuild -> E.EBuild
fixSrc serverURI p ebuild =
ebuild {
- src_uri = show $ serverURI {
+ E.src_uri = show $ serverURI {
uriPath =
uriPath serverURI
</> display (pkgName p)
@@ -372,7 +237,7 @@ fixSrc serverURI p ebuild =
<.> "tar.gz"
},
E.homepage = case E.homepage ebuild of
- "" -> "http://hackage.haskell.org/cgi-bin/hackage-scripts/package/"
+ "" -> "http://hackage.haskell.org/package/"
++ display (pkgName p)
x -> x
}
diff --git a/Merge/Dependencies.hs b/Merge/Dependencies.hs
new file mode 100644
index 0000000..361f551
--- /dev/null
+++ b/Merge/Dependencies.hs
@@ -0,0 +1,259 @@
+{- | Merge a package from hackage to an ebuild.
+
+Merging a library
+=================
+
+Compile time:
+ ghc
+ cabal
+ build tools
+ deps (haskell dependencies)
+ extra-libs (c-libs)
+ pkg-config (c-libs)
+
+Run time:
+ ghc
+ deps (haskell dependencies)
+ extra-libs (c-libs)
+ pkg-config (c-libs)
+
+RDEPEND="ghc ${DEPS} ${EXTRALIBS}"
+DEPEND="${RDEPEND} cabal ${BUILDTOOLS}"
+
+Merging an executable
+=====================
+Packages with both executable and library must be treated as libraries, as it will impose a stricter DEPEND.
+
+Compile time:
+ ghc
+ cabal
+ build tools
+ deps (haskell dependencies)
+ extra-libs (c-libs)
+ pkg-config (c-libs)
+
+Run time:
+ extra-libs (c-libs)
+ pkg-config (c-libs)
+
+RDEPEND="${EXTRALIBS}"
+DEPEND="${RDEPEND} ghc cabal ${DEPS} ${BUILDTOOLS}"
+
+-}
+
+module Merge.Dependencies
+ ( EDep(..)
+ , resolveDependencies
+ ) where
+
+import Distribution.PackageDescription ( PackageDescription(..)
+ , libBuildInfo
+ , buildInfo
+ , buildable
+ , extraLibs
+ , buildTools
+ , pkgconfigDepends
+ , hasLibs )
+import Data.Maybe ( isNothing )
+import Data.List ( nub )
+
+import qualified Distribution.Package as Cabal
+
+import qualified Portage.PackageId as Portage
+import qualified Portage.Dependency as Portage
+import qualified Cabal2Ebuild as C2E
+
+import Debug.Trace ( trace )
+
+-- | Dependencies of an ebuild
+data EDep = EDep
+ {
+ rdep :: [Portage.Dependency],
+ rdep_e :: [String],
+ dep :: [Portage.Dependency],
+ dep_e :: [String]
+ }
+
+emptyEDep :: EDep
+emptyEDep = EDep
+ {
+ rdep = [],
+ rdep_e = [],
+ dep = [],
+ dep_e = []
+ }
+
+resolveDependencies :: PackageDescription -> EDep
+resolveDependencies pkg =
+ edeps
+ {
+ dep = Portage.simplify_deps ( dep edeps),
+ rdep = Portage.simplify_deps (rdep edeps)
+ -- todo: if rdep includes cabal or ghc, make sure it's the same
+ -- version as in dep
+ }
+ where
+ hasBuildableExes p = any (buildable . buildInfo) . executables $ p
+ treatAsLibrary = (not . hasBuildableExes) pkg || hasLibs pkg
+ haskell_deps = haskellDependencies pkg
+ cabal_dep = cabalDependency pkg
+ ghc_dep = ghcDependency pkg
+ extra_libs = findCLibs pkg
+ build_tools = buildToolsDependencies pkg
+ pkg_config = pkgConfigDependencies pkg
+ edeps
+ | treatAsLibrary = emptyEDep
+ {
+ dep = cabal_dep
+ : build_tools,
+ dep_e = [ "${RDEPEND}" ],
+ rdep = ghc_dep
+ : haskell_deps
+ ++ extra_libs
+ ++ pkg_config
+ }
+ | otherwise = emptyEDep
+ {
+ dep = ghc_dep
+ : cabal_dep
+ : build_tools
+ ++ haskell_deps,
+ dep_e = [ "${RDEPEND}" ],
+ rdep = extra_libs ++ pkg_config
+ }
+
+---------------------------------------------------------------
+-- Haskell packages
+---------------------------------------------------------------
+
+haskellDependencies :: PackageDescription -> [Portage.Dependency]
+haskellDependencies pkg =
+ Portage.simplify_deps
+ $ C2E.convertDependencies (Portage.Category "dev-haskell") (buildDepends pkg)
+
+---------------------------------------------------------------
+-- Cabal Dependency
+---------------------------------------------------------------
+
+cabalDependency :: PackageDescription -> Portage.Dependency
+cabalDependency pkg =
+ head $ C2E.convertDependency (Portage.Category "dev-haskell")
+ (Cabal.Dependency (Cabal.PackageName "Cabal")
+ (descCabalVersion pkg))
+
+---------------------------------------------------------------
+-- GHC Dependency
+---------------------------------------------------------------
+
+ghcDependency :: PackageDescription -> Portage.Dependency
+ghcDependency _pkg = C2E.default_ghc_dependency
+
+---------------------------------------------------------------
+-- C Libraries
+---------------------------------------------------------------
+
+findCLibs :: PackageDescription -> [Portage.Dependency]
+findCLibs (PackageDescription { library = lib, executables = exes }) =
+ [ trace ("WARNING: This package depends on a C library we don't know the portage name for: " ++ p ++ ". Check the generated ebuild.")
+ (Portage.AnyVersionOf (Portage.mkPackageName "unknown-c-lib" p))
+ | p <- notFound
+ ] ++
+ found
+ where
+ libE = maybe [] (extraLibs.libBuildInfo) lib
+ exeE = concatMap extraLibs (filter buildable (map buildInfo exes))
+ allE = libE ++ exeE
+
+ notFound = [ p | p <- allE, isNothing (staticTranslateExtraLib p) ]
+ found = [ p | Just p <- map staticTranslateExtraLib allE ]
+
+
+staticTranslateExtraLib :: String -> Maybe Portage.Dependency
+staticTranslateExtraLib lib = lookup lib m
+ where
+ m = [ ("z", Portage.AnyVersionOf (Portage.mkPackageName "sys-libs" "zlib"))
+ , ("bz2", Portage.AnyVersionOf (Portage.mkPackageName "sys-libs" "bzlib"))
+ , ("mysqlclient", Portage.LaterVersionOf (Portage.Version [4,0] Nothing [] 0) (Portage.mkPackageName "virtual" "mysql"))
+ , ("pq", Portage.LaterVersionOf (Portage.Version [7] Nothing [] 0) (Portage.mkPackageName "virtual" "postgresql-base"))
+ , ("ev", Portage.AnyVersionOf (Portage.mkPackageName "dev-libs" "libev"))
+ ]
+
+---------------------------------------------------------------
+-- Build Tools
+---------------------------------------------------------------
+
+buildToolsDependencies :: PackageDescription -> [Portage.Dependency]
+buildToolsDependencies (PackageDescription { library = lib, executables = exes }) = nub $
+ [ case pkg of
+ Just p -> p
+ Nothing -> trace ("WARNING: Unknown build tool '" ++ pn ++ "'. Check the generated ebuild.")
+ (Portage.AnyVersionOf (Portage.mkPackageName "unknown-build-tool" pn))
+ | Cabal.Dependency (Cabal.PackageName pn) _range <- cabalDeps
+ , pkg <- return (lookup pn buildToolsTable)
+ ]
+ where
+ cabalDeps = depL ++ depE
+ depL = maybe [] (buildTools.libBuildInfo) lib
+ depE = concatMap buildTools (filter buildable (map buildInfo exes))
+
+buildToolsTable :: [(String, Portage.Dependency)]
+buildToolsTable =
+ [ ("happy", Portage.AnyVersionOf (Portage.mkPackageName "dev-haskell" "happy"))
+ , ("alex", Portage.AnyVersionOf (Portage.mkPackageName "dev-haskell" "alex"))
+ , ("c2hs", Portage.AnyVersionOf (Portage.mkPackageName "dev-haskell" "c2hs"))
+ , ("gtk2hsTypeGen", Portage.AnyVersionOf (Portage.mkPackageName "dev-haskell" "gtk2hs-buildtools"))
+ , ("gtk2hsHookGenerator", Portage.AnyVersionOf (Portage.mkPackageName "dev-haskell" "gtk2hs-buildtools"))
+ , ("gtk2hsC2hs", Portage.AnyVersionOf (Portage.mkPackageName "dev-haskell" "gtk2hs-buildtools"))
+ ]
+
+---------------------------------------------------------------
+-- pkg-config
+---------------------------------------------------------------
+
+pkgConfigDependencies :: PackageDescription -> [Portage.Dependency]
+pkgConfigDependencies (PackageDescription { library = lib, executables = exes }) = nub $ resolvePkgConfigs cabalDeps
+ where
+ cabalDeps = depL ++ depE
+ depL = maybe [] (pkgconfigDepends.libBuildInfo) lib
+ depE = concatMap pkgconfigDepends (filter buildable (map buildInfo exes))
+
+resolvePkgConfigs :: [Cabal.Dependency] -> [Portage.Dependency]
+resolvePkgConfigs cdeps =
+ [ case resolvePkgConfig pkg of
+ Just d -> d
+ Nothing -> trace ("WARNING: Could not resolve pkg-config: " ++ pn ++ ". Check generated ebuild.")
+ (Portage.AnyVersionOf (Portage.mkPackageName "unknown-pkg-config" pn))
+ | pkg@(Cabal.Dependency (Cabal.PackageName pn) _range) <- cdeps ]
+
+resolvePkgConfig :: Cabal.Dependency -> Maybe Portage.Dependency
+resolvePkgConfig (Cabal.Dependency (Cabal.PackageName pn) _cabalVersion) = do
+ (cat,portname) <- lookup pn table
+ return . head $ (C2E.convertDependency (Portage.Category cat) (Cabal.Dependency (Cabal.PackageName portname) _cabalVersion))
+
+table :: [(String, (String, String))]
+table =
+ [("gconf-2.0", ("gnome-base", "gconf"))
+ ,("gthread-2.0", ("dev-libs", "glib")) -- should be slot 2
+ ,("gtk+-2.0", ("x11-libs", "gtk+")) -- should be slot 2
+ ,("cairo", ("x11-libs", "cairo"))
+ ,("cairo-ps", ("x11-libs", "cairo"))
+ ,("cairo-pdf", ("x11-libs", "cairo"))
+ ,("cairo-svg", ("x11-libs", "cairo")) -- need [svg] for dev-haskell/cairo
+ ,("pango", ("x11-libs", "pango"))
+ ,("gio-2.0", ("dev-libs", "glib"))
+ ,("libglade-2.0", ("gnome-base", "libglade"))
+ ,("gnome-vfs-2.0", ("gnome-base", "gnome-vfs"))
+ ,("gnome-vfs-module-2.0", ("gnome-base", "gnome-vfs"))
+ ,("webkit-1.0", ("net-libs","webkit-gtk"))
+ ,("gstreamer-0.10", ("media-libs", "gstreamer"))
+ ,("gstreamer-audio-0.10", ("media-libs","gst-plugins-base"))
+ ,("gstreamer-base-0.10", ("media-libs","gstreamer"))
+ ,("gstreamer-controller-0.10", ("media-libs", "gstreamer"))
+ ,("gstreamer-dataprotocol-0.10", ("media-libs", "gstreamer"))
+ ,("gstreamer-net-0.10", ("media-libs", "gstreamer"))
+ ,("gstreamer-plugins-base-0.10", ("media-libs", "gst-plugins-base"))
+ ,("gtksourceview-2.0", ("x11-libs", "gtksourceview"))
+ ,("librsvg-2.0", ("gnome-base","librsvg"))
+ ,("vte", ("x11-libs","vte"))
+ ,("gtkglext-1.0", ("x11-libs","gtkglext"))
+ ]
diff --git a/Portage/Dependency.hs b/Portage/Dependency.hs
index f0ffd87..0182f7e 100644
--- a/Portage/Dependency.hs
+++ b/Portage/Dependency.hs
@@ -1,47 +1,59 @@
module Portage.Dependency (
Dependency(..),
- showDepend,
simplify_deps
) where
import Portage.Version
-import Distribution.Text (display)
+import Distribution.Text ( display, Text(..) )
+
+import Portage.PackageId
+
+import qualified Text.PrettyPrint as Disp
+import Text.PrettyPrint ( (<>) )
import Data.Maybe ( fromJust, catMaybes )
import Data.List ( nub, groupBy, partition, sortBy )
import Data.Ord (comparing)
-type Package = String
type UseFlag = String
-data Dependency = AnyVersionOf Package
- | ThisVersionOf Version Package -- =package-version
- | LaterVersionOf Version Package -- >package-version
- | EarlierVersionOf Version Package -- <package-version
- | OrLaterVersionOf Version Package -- >=package-version
- | OrEarlierVersionOf Version Package -- <=package-version
- | DependEither Dependency Dependency -- depend || depend
+data Dependency = AnyVersionOf PackageName
+ | ThisVersionOf Version PackageName -- ~package-version
+ | LaterVersionOf Version PackageName -- >package-version
+ | EarlierVersionOf Version PackageName -- <package-version
+ | OrLaterVersionOf Version PackageName -- >=package-version
+ | OrEarlierVersionOf Version PackageName -- <=package-version
+ | DependEither [[Dependency]] -- || ( depend_group1 ..depend_groupN )
| DependIfUse UseFlag Dependency -- use? ( depend )
- | ThisMajorOf Version Package -- =package-version*
+ | ThisMajorOf Version PackageName -- =package-version*
deriving (Eq,Show)
-showDepend :: Dependency -> Package
-showDepend (AnyVersionOf p) = p
-showDepend (ThisVersionOf v p) = "~" ++ p ++ "-" ++ display v
-showDepend (LaterVersionOf v p) = ">" ++ p ++ "-" ++ display v
-showDepend (EarlierVersionOf v p) = "<" ++ p ++ "-" ++ display v
-showDepend (OrLaterVersionOf v p) = ">=" ++ p ++ "-" ++ display v
-showDepend (OrEarlierVersionOf v p) = "<=" ++ p ++ "-" ++ display v
-showDepend (DependEither dep1 dep2) = showDepend dep1
- ++ " || " ++ showDepend dep2
-showDepend (DependIfUse useflag dep@(DependEither _ _))
- = useflag ++ "? " ++ showDepend dep
-showDepend (DependIfUse useflag dep) = useflag ++ "? ( " ++ showDepend dep++ " )"
-showDepend (ThisMajorOf v p) = "=" ++ p ++ "-" ++ display v ++ "*"
+instance Text Dependency where
+ disp = showDepend
+
+(<->) :: Disp.Doc -> Disp.Doc -> Disp.Doc
+a <-> b = a <> Disp.char '-' <> b
+
+showDepend :: Dependency -> Disp.Doc
+showDepend (AnyVersionOf p) = disp p
+showDepend (ThisVersionOf v p) = Disp.char '~' <> disp p <-> disp v { versionRevision = 0 }
+showDepend (LaterVersionOf v p) = Disp.char '>' <> disp p <-> disp v
+showDepend (EarlierVersionOf v p) = Disp.char '<' <> disp p <-> disp v
+showDepend (OrLaterVersionOf v p) = Disp.text ">=" <> disp p <-> disp v
+showDepend (OrEarlierVersionOf v p) = Disp.text "<=" <> disp p <-> disp v
+showDepend (DependEither dep_groups0)
+ = Disp.text "|| " <> spaceParens dep_groups
+ where dep_groups = map (spaceParens . map disp) dep_groups0
+ spaceParens ds = Disp.parens (Disp.space <> Disp.hsep ds <> Disp.space)
+showDepend (DependIfUse useflag dep@(DependEither _))
+ = Disp.text useflag <> Disp.text "? " <> disp dep
+showDepend (DependIfUse useflag dep)
+ = Disp.text useflag <> Disp.text "? " <> Disp.parens (disp dep)
+showDepend (ThisMajorOf v p) = Disp.char '=' <> disp p <-> disp v <> Disp.char '*'
{- Here goes code for dependencies simplification -}
-simplify_group_table :: Package ->
+simplify_group_table :: PackageName ->
Maybe Version ->
Maybe Version ->
Maybe Version ->
@@ -50,7 +62,7 @@ simplify_group_table :: Package ->
-- simplify_group_table p ol l e oe exact
-- 1) trivial cases:
-simplify_group_table p Nothing Nothing Nothing Nothing Nothing = error $ p ++ ": unsolvable constraints"
+simplify_group_table p Nothing Nothing Nothing Nothing Nothing = error $ display p ++ ": unsolvable constraints"
simplify_group_table p (Just v) Nothing Nothing Nothing Nothing = [OrLaterVersionOf v p]
simplify_group_table p Nothing (Just v) Nothing Nothing Nothing = [LaterVersionOf v p]
simplify_group_table p Nothing Nothing (Just v) Nothing Nothing = [EarlierVersionOf v p]
@@ -122,7 +134,7 @@ simplify_group deps = simplify_group_table package
simplify_deps :: [Dependency] -> [Dependency]
simplify_deps deps = (concatMap (simplify_group.nub) $
groupBy cmpPkgName $
- sortBy (comparing getPackageString) groupable)
+ sortBy (comparing getPackagePart) groupable)
++ ungroupable
where (ungroupable, groupable) = partition ((==Nothing).getPackage) deps
--
@@ -130,16 +142,16 @@ simplify_deps deps = (concatMap (simplify_group.nub) $
cmpMaybe (Just p1) (Just p2) = p1 == p2
cmpMaybe _ _ = False
--
-getPackage :: Dependency -> Maybe Package
+getPackage :: Dependency -> Maybe PackageName
getPackage (AnyVersionOf package) = Just package
getPackage (ThisVersionOf _version package) = Just package
getPackage (LaterVersionOf _version package) = Just package
getPackage (EarlierVersionOf _version package) = Just package
getPackage (OrLaterVersionOf _version package) = Just package
getPackage (OrEarlierVersionOf _version package) = Just package
-getPackage (DependEither _dependency _Dependency) = Nothing
+getPackage (DependEither _dependency ) = Nothing
getPackage (DependIfUse _useFlag _Dependency) = Nothing
getPackage (ThisMajorOf _version package) = Just package
--
-getPackageString :: Dependency -> Package
-getPackageString dep = maybe "" id $ getPackage dep
+getPackagePart :: Dependency -> PackageName
+getPackagePart dep = fromJust (getPackage dep)
diff --git a/Portage/EBuild.hs b/Portage/EBuild.hs
new file mode 100644
index 0000000..417fa36
--- /dev/null
+++ b/Portage/EBuild.hs
@@ -0,0 +1,174 @@
+module Portage.EBuild
+ ( EBuild(..)
+ , ebuildTemplate
+ ) where
+
+import Distribution.Text ( Text(..), display )
+import qualified Text.PrettyPrint as Disp
+
+import Portage.Dependency
+
+import Distribution.License as Cabal
+
+data EBuild = EBuild {
+ name :: String,
+ version :: String,
+ description :: String,
+ homepage :: String,
+ src_uri :: String,
+ license :: Cabal.License,
+ slot :: String,
+ keywords :: [String],
+ iuse :: [String],
+ depend :: [Dependency],
+ depend_extra :: [String],
+ rdepend :: [Dependency],
+ rdepend_extra :: [String],
+ features :: [String],
+ my_pn :: Maybe String --If the package's name contains upper-case
+ }
+
+ebuildTemplate :: EBuild
+ebuildTemplate = EBuild {
+ name = "foobar",
+ version = "0.1",
+ description = "",
+ homepage = "",
+ src_uri = "",
+ license = Cabal.UnknownLicense "xxx UNKNOWN xxx",
+ slot = "0",
+ keywords = ["~amd64","~x86"],
+ iuse = [],
+ depend = [],
+ depend_extra = [],
+ rdepend = [],
+ rdepend_extra = [],
+ features = [],
+ my_pn = Nothing
+ }
+
+instance Text EBuild where
+ disp = Disp.text . showEBuild
+
+showEBuild :: EBuild -> String
+showEBuild ebuild =
+ ss "# Copyright 1999-2010 Gentoo Foundation". nl.
+ ss "# Distributed under the terms of the GNU General Public License v2". nl.
+ ss "# $Header: $". nl.
+ nl.
+ ss "CABAL_FEATURES=". quote' (sepBy " " $ features ebuild). nl.
+ ss "inherit haskell-cabal". nl.
+ nl.
+ (case my_pn ebuild of
+ Nothing -> id
+ Just pn -> ss "MY_PN=". quote pn. nl.
+ ss "MY_P=". quote "${MY_PN}-${PV}". nl. nl).
+ ss "DESCRIPTION=". quote (description ebuild). nl.
+ ss "HOMEPAGE=". quote (homepage ebuild). nl.
+ ss "SRC_URI=". quote (replaceVars (src_uri ebuild)).
+ (if null (src_uri ebuild) then ss "\t#Fixme: please fill in manually"
+ else id). nl.
+ nl.
+ ss "LICENSE=". quote (convertLicense . license $ ebuild).
+ (if null (licenseComment . license $ ebuild) then id
+ else ss "\t#". ss (licenseComment . license $ ebuild)). nl.
+ ss "SLOT=". quote (slot ebuild). nl.
+ ss "KEYWORDS=". quote' (sepBy " " $ keywords ebuild).nl.
+ ss "IUSE=". quote' (sepBy ", " $ iuse ebuild). nl.
+ nl.
+ dep_str "RDEPEND" (rdepend_extra ebuild) (rdepend ebuild).
+ dep_str "DEPEND" ( depend_extra ebuild) ( depend ebuild).
+ nl.
+ (case my_pn ebuild of
+ Nothing -> id
+ Just _ -> nl. ss "S=". quote ("${WORKDIR}/${MY_P}"). nl)
+ $ []
+ where replaceVars = replaceCommonVars (name ebuild) (my_pn ebuild) (version ebuild)
+
+ss :: String -> String -> String
+ss = showString
+
+sc :: Char -> String -> String
+sc = showChar
+
+nl :: String -> String
+nl = sc '\n'
+
+dep_str :: String -> [String] -> [Dependency] -> (String -> String)
+dep_str var extra deps = ss var. sc '='. quote' (sepBy "\n\t\t" $ extra ++ map display deps). nl
+
+quote :: String -> String -> String
+quote str = sc '"'. ss (esc str). sc '"'
+ where
+ esc = concatMap esc'
+ esc' '"' = "\""
+ esc' c = [c]
+
+quote' :: (String -> String) -> String -> String
+quote' str = sc '"'. str. sc '"'
+
+sepBy :: String -> [String] -> ShowS
+sepBy _ [] = id
+sepBy _ [x] = ss x
+sepBy s (x:xs) = ss x. ss s. sepBy s xs
+
+getRestIfPrefix ::
+ String -> -- ^ the prefix
+ String -> -- ^ the string
+ Maybe String
+getRestIfPrefix (p:ps) (x:xs) = if p==x then getRestIfPrefix ps xs else Nothing
+getRestIfPrefix [] rest = Just rest
+getRestIfPrefix _ [] = Nothing
+
+subStr ::
+ String -> -- ^ the search string
+ String -> -- ^ the string to be searched
+ Maybe (String,String) -- ^ Just (pre,post) if string is found
+subStr sstr str = case getRestIfPrefix sstr str of
+ Nothing -> if null str then Nothing else case subStr sstr (tail str) of
+ Nothing -> Nothing
+ Just (pre,post) -> Just (head str:pre,post)
+ Just rest -> Just ([],rest)
+
+replaceMultiVars ::
+ [(String,String)] -> -- ^ pairs of variable name and content
+ String -> -- ^ string to be searched
+ String -- ^ the result
+replaceMultiVars [] str = str
+replaceMultiVars whole@((pname,cont):rest) str = case subStr cont str of
+ Nothing -> replaceMultiVars rest str
+ Just (pre,post) -> (replaceMultiVars rest pre)++pname++(replaceMultiVars whole post)
+
+replaceCommonVars ::
+ String -> -- ^ PN
+ Maybe String -> -- ^ MYPN
+ String -> -- ^ PV
+ String -> -- ^ the string to be replaced
+ String
+replaceCommonVars pn mypn pv str
+ = replaceMultiVars
+ ([("${P}",pn++"-"++pv)]
+ ++ maybe [] (\x->[("${MY_P}",x++"-"++pv)]) mypn
+ ++[("${PN}",pn)]
+ ++ maybe [] (\x->[("${MY_PN}",x)]) mypn
+ ++[("${PV}",pv)]) str
+
+
+-- map the cabal license type to the gentoo license string format
+convertLicense :: Cabal.License -> String
+convertLicense (Cabal.GPL mv) = "GPL-" ++ (maybe "2" display mv) -- almost certainly version 2
+convertLicense (Cabal.LGPL mv) = "LGPL-" ++ (maybe "2.1" display mv) -- probably version 2.1
+convertLicense Cabal.BSD3 = "BSD"
+convertLicense Cabal.BSD4 = "BSD-4"
+convertLicense Cabal.PublicDomain = "public-domain"
+convertLicense Cabal.AllRightsReserved = ""
+convertLicense Cabal.MIT = "MIT"
+convertLicense _ = ""
+
+licenseComment :: Cabal.License -> String
+licenseComment Cabal.AllRightsReserved =
+ "Note: packages without a license cannot be included in portage"
+licenseComment Cabal.OtherLicense =
+ "Fixme: \"OtherLicense\", please fill in manually"
+licenseComment (Cabal.UnknownLicense _) = "Fixme: license unknown to cabal"
+licenseComment _ = ""
diff --git a/Portage/PackageId.hs b/Portage/PackageId.hs
index abc5569..2f4757a 100644
--- a/Portage/PackageId.hs
+++ b/Portage/PackageId.hs
@@ -5,6 +5,7 @@ module Portage.PackageId (
PackageName(..),
PackageId(..),
Portage.Version(..),
+ mkPackageName,
fromCabalPackageId,
toCabalPackageId,
parseFriendlyPackage,
@@ -48,6 +49,9 @@ instance Text PN where
-- ambiguity in identifiers like foo-1 (the 1 is the version number).
-}
+mkPackageName :: String -> String -> PackageName
+mkPackageName cat package = PackageName (Category cat) (Cabal.PackageName package)
+
fromCabalPackageId :: Category -> Cabal.PackageIdentifier -> PackageId
fromCabalPackageId category (Cabal.PackageIdentifier name version) =
PackageId (PackageName category (normalizeCabalPackageName name))
diff --git a/Portage/Version.hs b/Portage/Version.hs
index eefce55..97583d6 100644
--- a/Portage/Version.hs
+++ b/Portage/Version.hs
@@ -25,10 +25,11 @@ import qualified Text.PrettyPrint as Disp
import Text.PrettyPrint ((<>))
import qualified Data.Char as Char (isAlpha, isDigit)
-data Version = Version [Int] -- [1,42,3] ~= 1.42.3
- (Maybe Char) -- optional letter
- [Suffix]
- Int -- revision, 0 means none
+data Version = Version { versionNumber :: [Int] -- [1,42,3] ~= 1.42.3
+ , versionChar :: (Maybe Char) -- optional letter
+ , versionSuffix :: [Suffix]
+ , versionRevision :: Int -- revision, 0 means none
+ }
deriving (Eq, Ord, Show, Read)
data Suffix = Alpha Int | Beta Int | Pre Int | RC Int | P Int
diff --git a/hackport.cabal b/hackport.cabal
index d331ce8..455a7e9 100644
--- a/hackport.cabal
+++ b/hackport.cabal
@@ -1,5 +1,5 @@
Name: hackport
-Version: 0.2.6
+Version: 0.2.7
License: GPL
License-file: LICENSE
Author: Henning G√ľnther, Duncan Coutts, Lennart Kolmodin
@@ -67,6 +67,7 @@ Executable hackport
Portage.Overlay
Portage.Resolve
Portage.Host
+ Merge.Dependencies
Setup
Status
Merge