packages feed

hackport 0.2.6 → 0.2.7

raw patch · 9 files changed

+551/−409 lines, 9 files

Files

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