hackport 0.2.6 → 0.2.7
raw patch · 9 files changed
+551/−409 lines, 9 files
Files
- Cabal2Ebuild.hs +38/−213
- Main.hs +4/−3
- Merge.hs +22/−157
- Merge/Dependencies.hs +259/−0
- Portage/Dependency.hs +43/−31
- Portage/EBuild.hs +174/−0
- Portage/PackageId.hs +4/−0
- Portage/Version.hs +5/−4
- hackport.cabal +2/−1
Cabal2Ebuild.hs view
@@ -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 @@ , 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- }--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- }+default_ghc_dependency :: Dependency+default_ghc_dependency = OrLaterVersionOf (Version [6,8,1] Nothing [] 0) (Portage.mkPackageName "dev-lang" "ghc") -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 @@ ,"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
Main.hs view
@@ -40,7 +40,8 @@ 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 @@ 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 {
Merge.hs view
@@ -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.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.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 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 @@ 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 @@ 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 @@ | Dependency pn vr <- buildDepends pkgDesc0 ] in pkgDesc0 { buildDepends = deps }-- 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)+ edeps = Merge.resolveDependencies pkgDesc - -- 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 @@ (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 @@ 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 @@ (\_ -> 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 @@ <.> "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 }
+ Merge/Dependencies.hs view
@@ -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"))+ ]
Portage/Dependency.hs view
@@ -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 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_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 @@ 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)
+ Portage/EBuild.hs view
@@ -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 _ = ""
Portage/PackageId.hs view
@@ -5,6 +5,7 @@ PackageName(..), PackageId(..), Portage.Version(..),+ mkPackageName, fromCabalPackageId, toCabalPackageId, parseFriendlyPackage,@@ -47,6 +48,9 @@ -- each component must contain an alphabetic character, to avoid -- 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) =
Portage/Version.hs view
@@ -25,10 +25,11 @@ 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
hackport.cabal view
@@ -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 @@ Portage.Overlay Portage.Resolve Portage.Host+ Merge.Dependencies Setup Status Merge