Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: b45538acc2
Fetching contributors…

Cannot retrieve contributors at this time

file 125 lines (117 sloc) 5.512 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
-- A program for generating a Gentoo ebuild from a .cabal file
--
-- Author : Duncan Coutts <dcoutts@gentoo.org>
--
-- Created: 21 July 2005
--
-- Copyright (C) 2005 Duncan Coutts
--
-- This library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; either version 2
-- of the License, or (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- General Public License for more details.
--
-- |
-- Maintainer : haskell@gentoo.org
--
-- cabal2ebuild - a program for generating a Gentoo ebuild from a .cabal file
--
module Cabal2Ebuild
        (cabal2ebuild
        ,convertDependencies
        ,convertDependency) where

import qualified Distribution.PackageDescription as Cabal
                                                (PackageDescription(..))
import qualified Distribution.Package as Cabal (PackageIdentifier(..)
                                                , Dependency(..)
                                                , PackageName(..))
import qualified Distribution.Version as Cabal (VersionRange, foldVersionRange')
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

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,
    E.long_desc = if null (Cabal.description pkg) then Cabal.synopsis pkg
                                               else Cabal.description pkg,
    E.homepage = thisHomepage,
    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","hoogle"]
                        ++ if cabalPkgName == "hscolour" then [] else ["hscolour"])
                        ) (Cabal.library pkg) -- hscolour can't colour its own sources
  } where
        cabalPkgName = display $ Cabal.pkgName (Cabal.package pkg)
        hasExe = (not . null) (Cabal.executables pkg)
        thisHomepage = if (null $ Cabal.homepage pkg)
                         then E.homepage E.ebuildTemplate
                         else Cabal.homepage pkg

convertDependencies :: Portage.Category -> [Cabal.Dependency] -> [Dependency]
convertDependencies category = concatMap (convertDependency category)

convertDependency :: Portage.Category -> Cabal.Dependency -> [Dependency]
convertDependency _category (Cabal.Dependency pname@(Cabal.PackageName _name) _)
  | pname `elem` coreLibs = [] -- no explicit dep on core libs
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
    pn = Portage.PackageName category (Portage.normalizeCabalPackageName pname)
    convert :: Cabal.VersionRange -> [Dependency]
    convert = Cabal.foldVersionRange'
             ( [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 -- ^ @\"_ && _\"@ intersection
            )(\dp -> [AllOf dp ] -- ^ @\"(_)\"@ parentheses
            )
      where
      flatten :: [Dependency] -> [[Dependency]]
      flatten [DependEither ds] = concatMap flatten ds
      flatten other = [other]


coreLibs :: [Cabal.PackageName]
coreLibs = map Cabal.PackageName
  ["array"
  ,"base"
  ,"bytestring" -- intentionally no ebuild. use ghc's version
                  -- to avoid dreaded 'diamond dependency' problem
  ,"containers"
  ,"directory"
  --,"editline"
  ,"filepath" -- intentionally no ebuild. use ghc's version
  ,"ghc"
  ,"ghc-prim"
  ,"haskell98"
  ,"hpc" --has ebuild, but only in the overlay
  ,"integer" -- up to ghc-6.10
  ,"integer-gmp" -- ghc-6.12+
  ,"old-locale"
  ,"old-time"
  ,"packedstring"
  ,"pretty"
  ,"process"
  -- ,"random" -- not a core package since ghc-7.2
  ,"rts"
  -- ,"syb" -- was splitted off from ghc again
  ,"template-haskell"
  ,"unix" -- unsafe to upgrade
  ]
Something went wrong with that request. Please try again.