cabal-debian 4.0.5 → 4.0.6
raw patch · 6 files changed
+366/−293 lines, 6 filesdep +bytestringdep +networkdep +old-locale
Dependencies added: bytestring, network, old-locale, process-listlike, regex-compat, time
Files
- cabal-debian.cabal +21/−20
- changelog +6/−0
- src/Debian/Debianize/BuildDependencies.hs +287/−0
- src/Debian/Debianize/Finalize.hs +12/−258
- src/Debian/Debianize/Types.hs +29/−12
- src/Debian/Orphans.hs +11/−3
cabal-debian.cabal view
@@ -1,5 +1,5 @@ Name: cabal-debian-Version: 4.0.5+Version: 4.0.6 License: BSD3 License-File: debian/copyright Author: David Fox <dsf@seereason.com>@@ -140,10 +140,10 @@ Default: False Manual: True --- flag local-debian--- Description: Link directly to the source of the debian library--- Default: False--- Manual: True+flag local-debian+ Description: Link directly to the source of the debian library+ Default: False+ Manual: True Source-Repository head type: darcs@@ -179,6 +179,7 @@ Debian.Debianize Debian.Policy Distribution.Version.Invert+ Debian.Debianize.BuildDependencies Debian.Debianize.Bundled Debian.Debianize.Changelog Debian.Debianize.DebianName@@ -200,11 +201,11 @@ Debian.Debianize.VersionSplits Other-Modules: Debian.Orphans--- if flag(local-debian)--- Hs-Source-Dirs: ., ../../haskell-debian--- Build-Depends: regex-compat, bytestring, process-listlike, network, old-locale, time--- else- Build-depends: debian >= 3.81+ if flag(local-debian)+ Hs-Source-Dirs: ., haskell-debian+ Build-Depends: regex-compat, bytestring, process-listlike, network, old-locale, time+ else+ Build-depends: debian >= 3.81 Executable cabal-debian Hs-Source-Dirs: src@@ -232,11 +233,11 @@ text, unix, utf8-string--- if flag(local-debian)--- Hs-Source-Dirs: ., ../../haskell-debian--- Build-Depends: regex-compat, bytestring, process-listlike, network, old-locale, time--- else- Build-Depends: debian >= 3.81+ if flag(local-debian)+ Hs-Source-Dirs: ., haskell-debian+ Build-Depends: regex-compat, bytestring, process-listlike, network, old-locale, time+ else+ Build-Depends: debian >= 3.81 Executable cabal-debian-tests Hs-Source-Dirs: src@@ -265,8 +266,8 @@ text, unix, utf8-string--- if flag(local-debian)--- Hs-Source-Dirs: ., ../../haskell-debian--- Build-Depends: regex-compat, bytestring, process-listlike, network, old-locale, time--- else- Build-depends: debian >= 3.81+ if flag(local-debian)+ Hs-Source-Dirs: ., haskell-debian+ Build-Depends: regex-compat, bytestring, process-listlike, network, old-locale, time+ else+ Build-depends: debian >= 3.81
changelog view
@@ -1,3 +1,9 @@+haskell-cabal-debian (4.0.6) unstable; urgency=low++ * Ifdef out duplicate instances for Cabal-1.18.0 - thanks to Tom Nielsen.++ -- David Fox <dsf@seereason.com> Tue, 28 Jan 2014 17:10:48 -0800+ haskell-cabal-debian (4.0.5) unstable; urgency=low * Changes for debian-3.81 - use the pretty printer in Debian.Pretty
+ src/Debian/Debianize/BuildDependencies.hs view
@@ -0,0 +1,287 @@+-- | Compute the debianization of a cabal package.+{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}+module Debian.Debianize.BuildDependencies+ ( debianBuildDeps+ , debianBuildDepsIndep+ ) where++import Control.Monad.State (MonadState(get))+import Data.Char (isSpace)+import Data.Function (on)+import Data.Lens.Lazy (access, getL)+import Data.List as List (filter, map, minimumBy, nub)+import Data.Map as Map (lookup, Map)+import Data.Maybe (catMaybes, fromMaybe)+import Data.Set as Set (singleton)+import qualified Data.Set as Set (member)+import Data.Version (showVersion, Version)+import Debian.Debianize.Bundled (ghcBuiltIn)+import Debian.Debianize.DebianName (mkPkgName, mkPkgName')+import Debian.Debianize.Monad as Monad (Atoms, DebT)+import qualified Debian.Debianize.Types as T (buildDepends, buildDependsIndep, compiler, debianNameMap, epochMap, execMap, extraLibMap, missingDependencies, noDocumentationLibrary, noProfilingLibrary)+import qualified Debian.Debianize.Types.BinaryDebDescription as B (PackageType(Development, Documentation, Profiling))+import Debian.Debianize.VersionSplits (packageRangesFromVersionSplits)+import Debian.Orphans ()+import Debian.Relation (BinPkgName, Relation(..), Relations)+import qualified Debian.Relation as D (BinPkgName(BinPkgName), Relation(..), Relations, VersionReq(EEQ, GRE, LTE, SGR, SLT))+import Debian.Version (DebianVersion, parseDebianVersion)+import Distribution.Package (Dependency(..), PackageIdentifier(..), PackageName(PackageName))+import Distribution.PackageDescription (PackageDescription)+import Distribution.PackageDescription as Cabal (allBuildInfo, BuildInfo(..), BuildInfo(buildTools, extraLibs, pkgconfigDepends), Executable(..))+import qualified Distribution.PackageDescription as Cabal (PackageDescription(buildDepends, executables, package))+import Distribution.Version (anyVersion, asVersionIntervals, earlierVersion, foldVersionRange', fromVersionIntervals, intersectVersionRanges, isNoVersion, laterVersion, orEarlierVersion, orLaterVersion, toVersionIntervals, unionVersionRanges, VersionRange, withinVersion)+import Distribution.Version.Invert (invertVersionRange)+import Prelude hiding (init, log, map, unlines, unlines, writeFile)+import System.Exit (ExitCode(ExitSuccess))+import System.IO.Unsafe (unsafePerformIO)+import System.Process (readProcessWithExitCode)++data Dependency_+ = BuildDepends Dependency+ | BuildTools Dependency+ | PkgConfigDepends Dependency+ | ExtraLibs Relations+ deriving (Eq, Show)++-- | In cabal a self dependency probably means the library is needed+-- while building the executables. In debian it would mean that the+-- package needs an earlier version of itself to build, so we use this+-- to filter such dependencies out.+selfDependency :: PackageIdentifier -> Dependency_ -> Bool+selfDependency pkgId (BuildDepends (Dependency name _)) = name == pkgName pkgId+selfDependency _ _ = False++unboxDependency :: Dependency_ -> Maybe Dependency+unboxDependency (BuildDepends d) = Just d+unboxDependency (BuildTools d) = Just d+unboxDependency (PkgConfigDepends d) = Just d+unboxDependency (ExtraLibs _) = Nothing -- Dependency (PackageName d) anyVersion++-- |Debian packages don't have per binary package build dependencies,+-- so we just gather them all up here.+allBuildDepends :: Monad m => [Dependency] -> [Dependency] -> [Dependency] -> [String] -> DebT m [Dependency_]+allBuildDepends buildDepends' buildTools' pkgconfigDepends' extraLibs' =+ do atoms <- get+ return $ nub $ List.map BuildDepends buildDepends' +++ List.map BuildTools buildTools' +++ List.map PkgConfigDepends pkgconfigDepends' +++ [ExtraLibs (fixDeps atoms extraLibs')]+ where+ fixDeps :: Atoms -> [String] -> Relations+ fixDeps atoms xs =+ concatMap (\ cab -> fromMaybe [[D.Rel (D.BinPkgName ("lib" ++ cab ++ "-dev")) Nothing Nothing]]+ (Map.lookup cab (getL T.extraLibMap atoms))) xs++-- The haskell-cdbs package contains the hlibrary.mk file with+-- the rules for building haskell packages.+debianBuildDeps :: Monad m => PackageDescription -> DebT m D.Relations+debianBuildDeps pkgDesc =+ do deb <- get+ cDeps <- cabalDeps+ let bDeps = getL T.buildDepends deb+ prof = (/= singleton True) $ getL T.noProfilingLibrary deb+ let xs = nub $ [[D.Rel (D.BinPkgName "debhelper") (Just (D.GRE (parseDebianVersion ("7.0" :: String)))) Nothing],+ [D.Rel (D.BinPkgName "haskell-devscripts") (Just (D.GRE (parseDebianVersion ("0.8" :: String)))) Nothing],+ anyrel "cdbs",+ anyrel "ghc"] +++ bDeps +++ (if prof then [anyrel "ghc-prof"] else []) +++ cDeps+ filterMissing xs+ where+ cabalDeps =+ do deps <- allBuildDepends+ (Cabal.buildDepends pkgDesc ++ concatMap (Cabal.targetBuildDepends . Cabal.buildInfo) (Cabal.executables pkgDesc))+ (concatMap buildTools . allBuildInfo $ pkgDesc)+ (concatMap pkgconfigDepends . allBuildInfo $ pkgDesc)+ (concatMap extraLibs . allBuildInfo $ pkgDesc)+ mapM buildDependencies (List.filter (not . selfDependency (Cabal.package pkgDesc)) deps) >>= return . concat++debianBuildDepsIndep :: Monad m => PackageDescription -> DebT m D.Relations+debianBuildDepsIndep pkgDesc =+ do doc <- get >>= return . (/= singleton True) . getL T.noDocumentationLibrary+ bDeps <- get >>= return . getL T.buildDependsIndep+ cDeps <- cabalDeps+ let xs = if doc+ then nub $ [anyrel "ghc-doc"] ++ bDeps ++ concat cDeps+ else []+ filterMissing xs+ where+ cabalDeps =+ do deps <- allBuildDepends+ (Cabal.buildDepends pkgDesc) (concatMap buildTools . allBuildInfo $ pkgDesc)+ (concatMap pkgconfigDepends . allBuildInfo $ pkgDesc) (concatMap extraLibs . allBuildInfo $ pkgDesc)+ let deps' = List.filter (not . selfDependency (Cabal.package pkgDesc)) deps+ mapM docDependencies deps'+{-+ cabalDeps deb =+ concat . List.map (\ x -> evalDebM (docDependencies x) deb)+ $ List.filter (not . selfDependency (Cabal.package pkgDesc))+ $ evalDebM+ (allBuildDepends+ (Cabal.buildDepends pkgDesc) (concatMap buildTools . allBuildInfo $ pkgDesc)+ (concatMap pkgconfigDepends . allBuildInfo $ pkgDesc) (concatMap extraLibs . allBuildInfo $ pkgDesc))+ deb+-}++-- | The documentation dependencies for a package include the+-- documentation package for any libraries which are build+-- dependencies, so we have access to all the cross references.+docDependencies :: Monad m => Dependency_ -> DebT m D.Relations+docDependencies (BuildDepends (Dependency name ranges)) = dependencies B.Documentation name ranges+docDependencies _ = return []++-- | The Debian build dependencies for a package include the profiling+-- libraries and the documentation packages, used for creating cross+-- references. Also the packages associated with extra libraries.+buildDependencies :: Monad m => Dependency_ -> DebT m D.Relations+buildDependencies (BuildDepends (Dependency name ranges)) =+ do dev <- dependencies B.Development name ranges+ prof <- dependencies B.Profiling name ranges+ return $ dev ++ prof+buildDependencies dep@(ExtraLibs _) =+ do mp <- get >>= return . getL T.execMap+ return $ concat $ adapt mp dep+buildDependencies dep =+ case unboxDependency dep of+ Just (Dependency _name _ranges) ->+ do mp <- get >>= return . getL T.execMap+ return $ concat $ adapt mp dep+ Nothing ->+ return []++adapt :: Map.Map String Relations -> Dependency_ -> [Relations]+adapt mp (PkgConfigDepends (Dependency (PackageName pkg) _)) =+ maybe (aptFile pkg) (: []) (Map.lookup pkg mp)+adapt mp (BuildTools (Dependency (PackageName pkg) _)) =+ maybe (aptFile pkg) (: []) (Map.lookup pkg mp)+adapt _flags (ExtraLibs x) = [x]+adapt _flags (BuildDepends (Dependency (PackageName pkg) _)) = [[[D.Rel (D.BinPkgName pkg) Nothing Nothing]]]++-- There are two reasons this may not work, or may work+-- incorrectly: (1) the build environment may be a different+-- distribution than the parent environment (the environment the+-- autobuilder was run from), so the packages in that+-- environment might have different names, and (2) the package+-- we are looking for may not be installed in the parent+-- environment.+aptFile :: String -> [Relations] -- Maybe would probably be more correct+aptFile pkg =+ unsafePerformIO $+ do ret <- readProcessWithExitCode "apt-file" ["-l", "search", pkg ++ ".pc"] ""+ return $ case ret of+ (ExitSuccess, out, _) ->+ case takeWhile (not . isSpace) out of+ "" -> error $ "Unable to locate a debian package containing the build tool " ++ pkg +++ ", try using --exec-map " ++ pkg ++ "=<debname> or execMap " ++ show pkg +++ " [[Rel (BinPkgName \"<debname>\") Nothing Nothing]]"+ s -> [[[D.Rel (D.BinPkgName s) Nothing Nothing]]]+ _ -> []++anyrel :: String -> [D.Relation]+anyrel x = anyrel' (D.BinPkgName x)++anyrel' :: D.BinPkgName -> [D.Relation]+anyrel' x = [D.Rel x Nothing Nothing]++-- | Turn a cabal dependency into debian dependencies. The result+-- needs to correspond to a single debian package to be installed,+-- so we will return just an OrRelation.+dependencies :: Monad m => B.PackageType -> PackageName -> VersionRange -> DebT m Relations+dependencies typ name cabalRange =+ do atoms <- get+ -- Compute a list of alternative debian dependencies for+ -- satisfying a cabal dependency. The only caveat is that+ -- we may need to distribute any "and" dependencies implied+ -- by a version range over these "or" dependences.+ let alts = case Map.lookup name (getL T.debianNameMap atoms) of+ -- If there are no splits for this package just return the single dependency for the package+ Nothing -> [(mkPkgName name typ, cabalRange')]+ -- If there are splits create a list of (debian package name, VersionRange) pairs+ Just splits' -> List.map (\ (n, r) -> (mkPkgName' n typ, r)) (packageRangesFromVersionSplits splits')+ mapM convert alts >>= mapM (doBundled typ name) . convert' . canonical . Or . catMaybes+ where+ convert :: Monad m => (BinPkgName, VersionRange) -> DebT m (Maybe (Rels Relation))+ convert (dname, range) =+ case isNoVersion range''' of+ True -> return Nothing+ False ->+ foldVersionRange'+ (return $ Rel' (D.Rel dname Nothing Nothing))+ (\ v -> debianVersion' name v >>= \ dv -> return $ Rel' (D.Rel dname (Just (D.EEQ dv)) Nothing))+ (\ v -> debianVersion' name v >>= \ dv -> return $ Rel' (D.Rel dname (Just (D.SGR dv)) Nothing))+ (\ v -> debianVersion' name v >>= \ dv -> return $ Rel' (D.Rel dname (Just (D.SLT dv)) Nothing))+ (\ v -> debianVersion' name v >>= \ dv -> return $ Rel' (D.Rel dname (Just (D.GRE dv)) Nothing))+ (\ v -> debianVersion' name v >>= \ dv -> return $ Rel' (D.Rel dname (Just (D.LTE dv)) Nothing))+ (\ x y -> debianVersion' name x >>= \ dvx ->+ debianVersion' name y >>= \ dvy ->+ return $ And [Rel' (D.Rel dname (Just (D.GRE dvx)) Nothing),+ Rel' (D.Rel dname (Just (D.SLT dvy)) Nothing)])+ (\ x y -> x >>= \ x' -> y >>= \ y' -> return $ Or [x', y'])+ (\ x y -> x >>= \ x' -> y >>= \ y' -> return $ And [x', y'])+ id+ range''' >>= return . Just+ where+ -- Choose the simpler of the two+ range''' = canon (simpler range' range'')+ -- Unrestrict the range for versions that we know don't exist for this debian package+ range'' = canon (unionVersionRanges range' (invertVersionRange range))+ -- Restrict the range to the versions specified for this debian package+ range' = intersectVersionRanges cabalRange' range+ -- When we see a cabal equals dependency we need to turn it into+ -- a wildcard because the resulting debian version numbers have+ -- various suffixes added.+ cabalRange' =+ foldVersionRange'+ anyVersion+ withinVersion -- <- Here we are turning equals into wildcard+ laterVersion+ earlierVersion+ orLaterVersion+ orEarlierVersion+ (\ lb ub -> intersectVersionRanges (orLaterVersion lb) (earlierVersion ub))+ unionVersionRanges+ intersectVersionRanges+ id+ cabalRange+ simpler v1 v2 = minimumBy (compare `on` (length . asVersionIntervals)) [v1, v2]+ -- Simplify a VersionRange+ canon = fromVersionIntervals . toVersionIntervals++-- If a package is bundled with the compiler we make the+-- compiler a substitute for that package. If we were to+-- specify the virtual package (e.g. libghc-base-dev) we would+-- have to make sure not to specify a version number.+doBundled :: Monad m => B.PackageType -> PackageName -> [D.Relation] -> DebT m [D.Relation]+doBundled typ name rels =+ do comp <- access T.compiler >>= return . fromMaybe (error "no Compiler value")+ case ghcBuiltIn comp name of+ True -> return $ rels ++ [D.Rel (compilerPackageName typ) Nothing Nothing]+ False -> return rels+ where+ compilerPackageName B.Documentation = D.BinPkgName "ghc-doc"+ compilerPackageName B.Profiling = D.BinPkgName "ghc-prof"+ compilerPackageName B.Development = D.BinPkgName "ghc"+ compilerPackageName _ = D.BinPkgName "ghc" -- whatevs++-- Convert a cabal version to a debian version, adding an epoch number if requested+debianVersion' :: Monad m => PackageName -> Version -> DebT m DebianVersion+debianVersion' name v =+ do atoms <- get+ return $ parseDebianVersion (maybe "" (\ n -> show n ++ ":") (Map.lookup name (getL T.epochMap atoms)) ++ showVersion v)++data Rels a = And {unAnd :: [Rels a]} | Or {unOr :: [Rels a]} | Rel' {unRel :: a} deriving Show++convert' :: Rels a -> [[a]]+convert' = List.map (List.map unRel . unOr) . unAnd . canonical++-- | return and of ors of rel+canonical :: Rels a -> Rels a+canonical (Rel' rel) = And [Or [Rel' rel]]+canonical (And rels) = And $ concatMap (unAnd . canonical) rels+canonical (Or rels) = And . List.map Or $ sequence $ List.map (concat . List.map unOr . unAnd . canonical) $ rels++filterMissing :: Monad m => [[Relation]] -> DebT m [[Relation]]+filterMissing rels =+ get >>= \ atoms -> return $+ List.filter (/= []) (List.map (List.filter (\ (Rel name _ _) -> not (Set.member name (getL T.missingDependencies atoms)))) rels)
src/Debian/Debianize/Finalize.hs view
@@ -11,52 +11,43 @@ import Control.Monad.State (get, modify) import Control.Monad.Trans (liftIO, MonadIO) import Data.ByteString.Lazy.UTF8 (fromString)-import Data.Char (isSpace, toLower)+import Data.Char (toLower) import Data.Digest.Pure.MD5 (md5)-import Data.Function (on) import Data.Lens.Lazy (access, getL)-import Data.List as List (filter, intercalate, map, minimumBy, nub, unlines)+import Data.List as List (intercalate, map, nub, unlines) import Data.Map as Map (delete, elems, lookup, map, Map, toList, unionsWith)-import Data.Maybe (catMaybes, fromMaybe, isJust)+import Data.Maybe (fromMaybe, isJust) import Data.Monoid ((<>)) import Data.Set as Set (difference, filter, fromList, map, null, Set, singleton, toList, union, unions)-import qualified Data.Set as Set (member) import Data.Set.Extra as Set (mapM_) import Data.Text as Text (pack, unlines, unpack)-import Data.Version (showVersion, Version) import Debian.Changes (ChangeLog(..), ChangeLogEntry(..))-import Debian.Debianize.Bundled (ghcBuiltIn)+import Debian.Debianize.BuildDependencies (debianBuildDeps, debianBuildDepsIndep) import Debian.Debianize.Changelog (dropFutureEntries)-import Debian.Debianize.DebianName (debianName, mkPkgName, mkPkgName')+import Debian.Debianize.DebianName (debianName) import Debian.Debianize.Goodies (backupAtoms, describe, execAtoms, serverAtoms, siteAtoms, watchAtom) import Debian.Debianize.Input (dataDir, inputCabalization, inputChangeLog, inputMaintainer)-import Debian.Debianize.Monad as Monad (Atoms, DebT)+import Debian.Debianize.Monad as Monad (DebT) import Debian.Debianize.Options (compileCommandlineArgs, compileEnvironmentArgs) import Debian.Debianize.Prelude ((%=), (+++=), (+=), foldEmpty, fromEmpty, fromSingleton, (~=), (~?=)) import Debian.Debianize.Types (Top)-import qualified Debian.Debianize.Types as T-import qualified Debian.Debianize.Types.Atoms as A-import qualified Debian.Debianize.Types.BinaryDebDescription as B-import Debian.Debianize.VersionSplits (packageRangesFromVersionSplits)+import qualified Debian.Debianize.Types as T (apacheSite, backups, binaryArchitectures, binaryPackages, binarySection, breaks, buildDepends, buildDependsIndep, buildDir, builtUsing, changelog, comments, compat, conflicts, debianDescription, debVersion, depends, epochMap, executable, extraDevDeps, extraLibMap, file, install, installCabalExec, installCabalExecTo, installData, installDir, installTo, intermediateFiles, license, link, maintainer, noDocumentationLibrary, noProfilingLibrary, packageDescription, packageType, preDepends, provides, recommends, replaces, revision, rulesFragments, serverInfo, source, sourcePackageName, sourcePriority, sourceSection, suggests, utilsPackageNames, verbosity, watch, website)+import qualified Debian.Debianize.Types.Atoms as A (InstallFile(execName, sourceDir), showAtoms)+import qualified Debian.Debianize.Types.BinaryDebDescription as B (BinaryDebDescription, package, PackageType(Development, Documentation, Exec, Profiling, Source', Utilities)) import Debian.Orphans () import Debian.Policy (getDebhelperCompatLevel, haskellMaintainer, PackageArchitectures(Any, All), PackagePriority(Optional), Section(..)) import Debian.Pretty (pretty) import Debian.Relation (BinPkgName, BinPkgName(BinPkgName), Relation, Relation(Rel), Relations)-import qualified Debian.Relation as D (BinPkgName(BinPkgName), Relation(..), Relations, VersionReq(EEQ, GRE, LTE, SGR, SLT))+import qualified Debian.Relation as D (BinPkgName(BinPkgName), Relation(..)) import Debian.Release (parseReleaseName) import Debian.Time (getCurrentLocalRFC822Time) import Debian.Version (buildDebianVersion, DebianVersion, parseDebianVersion) import Distribution.Package (Dependency(..), PackageIdentifier(..), PackageName(PackageName)) import Distribution.PackageDescription (PackageDescription)-import Distribution.PackageDescription as Cabal (allBuildInfo, BuildInfo(buildTools, extraLibs, pkgconfigDepends), Executable(..), BuildInfo(..))-import qualified Distribution.PackageDescription as Cabal (PackageDescription(buildDepends, dataFiles, executables, library, package), PackageDescription(license))-import Distribution.Version (anyVersion, asVersionIntervals, earlierVersion, foldVersionRange', fromVersionIntervals, intersectVersionRanges, isNoVersion, laterVersion, orEarlierVersion, orLaterVersion, toVersionIntervals, unionVersionRanges, VersionRange, withinVersion)-import Distribution.Version.Invert (invertVersionRange)+import Distribution.PackageDescription as Cabal (allBuildInfo, BuildInfo(buildable, extraLibs), Executable(buildInfo, exeName))+import qualified Distribution.PackageDescription as Cabal (PackageDescription(dataFiles, executables, library, license, package)) import Prelude hiding (init, log, map, unlines, unlines, writeFile)-import System.Exit (ExitCode(ExitSuccess)) import System.FilePath ((<.>), (</>), makeRelative, splitFileName, takeDirectory, takeFileName)-import System.IO.Unsafe (unsafePerformIO)-import System.Process (readProcessWithExitCode) -- | Given an Atoms value, get any additional configuration -- information from the environment, read the cabal package@@ -447,245 +438,8 @@ | ExtraLibs Relations deriving (Eq, Show) --- | In cabal a self dependency probably means the library is needed--- while building the executables. In debian it would mean that the--- package needs an earlier version of itself to build, so we use this--- to filter such dependencies out.-selfDependency :: PackageIdentifier -> Dependency_ -> Bool-selfDependency pkgId (BuildDepends (Dependency name _)) = name == pkgName pkgId-selfDependency _ _ = False--unboxDependency :: Dependency_ -> Maybe Dependency-unboxDependency (BuildDepends d) = Just d-unboxDependency (BuildTools d) = Just d-unboxDependency (PkgConfigDepends d) = Just d-unboxDependency (ExtraLibs _) = Nothing -- Dependency (PackageName d) anyVersion---- |Debian packages don't have per binary package build dependencies,--- so we just gather them all up here.-allBuildDepends :: Monad m => [Dependency] -> [Dependency] -> [Dependency] -> [String] -> DebT m [Dependency_]-allBuildDepends buildDepends' buildTools' pkgconfigDepends' extraLibs' =- do atoms <- get- return $ nub $ List.map BuildDepends buildDepends' ++- List.map BuildTools buildTools' ++- List.map PkgConfigDepends pkgconfigDepends' ++- [ExtraLibs (fixDeps atoms extraLibs')]- where- fixDeps :: Atoms -> [String] -> Relations- fixDeps atoms xs =- concatMap (\ cab -> fromMaybe [[D.Rel (D.BinPkgName ("lib" ++ cab ++ "-dev")) Nothing Nothing]]- (Map.lookup cab (getL T.extraLibMap atoms))) xs---- The haskell-cdbs package contains the hlibrary.mk file with--- the rules for building haskell packages.-debianBuildDeps :: Monad m => PackageDescription -> DebT m D.Relations-debianBuildDeps pkgDesc =- do deb <- get- cDeps <- cabalDeps- let bDeps = getL T.buildDepends deb- prof = (/= singleton True) $ getL T.noProfilingLibrary deb- let xs = nub $ [[D.Rel (D.BinPkgName "debhelper") (Just (D.GRE (parseDebianVersion ("7.0" :: String)))) Nothing],- [D.Rel (D.BinPkgName "haskell-devscripts") (Just (D.GRE (parseDebianVersion ("0.8" :: String)))) Nothing],- anyrel "cdbs",- anyrel "ghc"] ++- bDeps ++- (if prof then [anyrel "ghc-prof"] else []) ++- cDeps- filterMissing xs- where- cabalDeps =- do deps <- allBuildDepends- (Cabal.buildDepends pkgDesc ++ concatMap (Cabal.targetBuildDepends . Cabal.buildInfo) (Cabal.executables pkgDesc))- (concatMap buildTools . allBuildInfo $ pkgDesc)- (concatMap pkgconfigDepends . allBuildInfo $ pkgDesc)- (concatMap extraLibs . allBuildInfo $ pkgDesc)- mapM buildDependencies (List.filter (not . selfDependency (Cabal.package pkgDesc)) deps) >>= return . concat--debianBuildDepsIndep :: Monad m => PackageDescription -> DebT m D.Relations-debianBuildDepsIndep pkgDesc =- do doc <- get >>= return . (/= singleton True) . getL T.noDocumentationLibrary- bDeps <- get >>= return . getL T.buildDependsIndep- cDeps <- cabalDeps- let xs = if doc- then nub $ [anyrel "ghc-doc"] ++ bDeps ++ concat cDeps- else []- filterMissing xs- where- cabalDeps =- do deps <- allBuildDepends- (Cabal.buildDepends pkgDesc) (concatMap buildTools . allBuildInfo $ pkgDesc)- (concatMap pkgconfigDepends . allBuildInfo $ pkgDesc) (concatMap extraLibs . allBuildInfo $ pkgDesc)- let deps' = List.filter (not . selfDependency (Cabal.package pkgDesc)) deps- mapM docDependencies deps'-{-- cabalDeps deb =- concat . List.map (\ x -> evalDebM (docDependencies x) deb)- $ List.filter (not . selfDependency (Cabal.package pkgDesc))- $ evalDebM- (allBuildDepends- (Cabal.buildDepends pkgDesc) (concatMap buildTools . allBuildInfo $ pkgDesc)- (concatMap pkgconfigDepends . allBuildInfo $ pkgDesc) (concatMap extraLibs . allBuildInfo $ pkgDesc))- deb--}---- | The documentation dependencies for a package include the--- documentation package for any libraries which are build--- dependencies, so we have access to all the cross references.-docDependencies :: Monad m => Dependency_ -> DebT m D.Relations-docDependencies (BuildDepends (Dependency name ranges)) = dependencies B.Documentation name ranges-docDependencies _ = return []---- | The Debian build dependencies for a package include the profiling--- libraries and the documentation packages, used for creating cross--- references. Also the packages associated with extra libraries.-buildDependencies :: Monad m => Dependency_ -> DebT m D.Relations-buildDependencies (BuildDepends (Dependency name ranges)) =- do dev <- dependencies B.Development name ranges- prof <- dependencies B.Profiling name ranges- return $ dev ++ prof-buildDependencies dep@(ExtraLibs _) =- do mp <- get >>= return . getL T.execMap- return $ concat $ adapt mp dep-buildDependencies dep =- case unboxDependency dep of- Just (Dependency _name _ranges) ->- do mp <- get >>= return . getL T.execMap- return $ concat $ adapt mp dep- Nothing ->- return []--adapt :: Map.Map String Relations -> Dependency_ -> [Relations]-adapt mp (PkgConfigDepends (Dependency (PackageName pkg) _)) =- maybe (aptFile pkg) (: []) (Map.lookup pkg mp)-adapt mp (BuildTools (Dependency (PackageName pkg) _)) =- maybe (aptFile pkg) (: []) (Map.lookup pkg mp)-adapt _flags (ExtraLibs x) = [x]-adapt _flags (BuildDepends (Dependency (PackageName pkg) _)) = [[[D.Rel (D.BinPkgName pkg) Nothing Nothing]]]---- There are two reasons this may not work, or may work--- incorrectly: (1) the build environment may be a different--- distribution than the parent environment (the environment the--- autobuilder was run from), so the packages in that--- environment might have different names, and (2) the package--- we are looking for may not be installed in the parent--- environment.-aptFile :: String -> [Relations] -- Maybe would probably be more correct-aptFile pkg =- unsafePerformIO $- do ret <- readProcessWithExitCode "apt-file" ["-l", "search", pkg ++ ".pc"] ""- return $ case ret of- (ExitSuccess, out, _) ->- case takeWhile (not . isSpace) out of- "" -> error $ "Unable to locate a debian package containing the build tool " ++ pkg ++- ", try using --exec-map " ++ pkg ++ "=<debname> or execMap " ++ show pkg ++- " [[Rel (BinPkgName \"<debname>\") Nothing Nothing]]"- s -> [[[D.Rel (D.BinPkgName s) Nothing Nothing]]]- _ -> []- anyrel :: String -> [D.Relation] anyrel x = anyrel' (D.BinPkgName x) anyrel' :: D.BinPkgName -> [D.Relation] anyrel' x = [D.Rel x Nothing Nothing]---- | Turn a cabal dependency into debian dependencies. The result--- needs to correspond to a single debian package to be installed,--- so we will return just an OrRelation.-dependencies :: Monad m => B.PackageType -> PackageName -> VersionRange -> DebT m Relations-dependencies typ name cabalRange =- do atoms <- get- -- Compute a list of alternative debian dependencies for- -- satisfying a cabal dependency. The only caveat is that- -- we may need to distribute any "and" dependencies implied- -- by a version range over these "or" dependences.- let alts = case Map.lookup name (getL T.debianNameMap atoms) of- -- If there are no splits for this package just return the single dependency for the package- Nothing -> [(mkPkgName name typ, cabalRange')]- -- If there are splits create a list of (debian package name, VersionRange) pairs- Just splits' -> List.map (\ (n, r) -> (mkPkgName' n typ, r)) (packageRangesFromVersionSplits splits')- mapM convert alts >>= mapM (doBundled typ name) . convert' . canonical . Or . catMaybes- where- convert :: Monad m => (BinPkgName, VersionRange) -> DebT m (Maybe (Rels Relation))- convert (dname, range) =- case isNoVersion range''' of- True -> return Nothing- False ->- foldVersionRange'- (return $ Rel' (D.Rel dname Nothing Nothing))- (\ v -> debianVersion' name v >>= \ dv -> return $ Rel' (D.Rel dname (Just (D.EEQ dv)) Nothing))- (\ v -> debianVersion' name v >>= \ dv -> return $ Rel' (D.Rel dname (Just (D.SGR dv)) Nothing))- (\ v -> debianVersion' name v >>= \ dv -> return $ Rel' (D.Rel dname (Just (D.SLT dv)) Nothing))- (\ v -> debianVersion' name v >>= \ dv -> return $ Rel' (D.Rel dname (Just (D.GRE dv)) Nothing))- (\ v -> debianVersion' name v >>= \ dv -> return $ Rel' (D.Rel dname (Just (D.LTE dv)) Nothing))- (\ x y -> debianVersion' name x >>= \ dvx ->- debianVersion' name y >>= \ dvy ->- return $ And [Rel' (D.Rel dname (Just (D.GRE dvx)) Nothing),- Rel' (D.Rel dname (Just (D.SLT dvy)) Nothing)])- (\ x y -> x >>= \ x' -> y >>= \ y' -> return $ Or [x', y'])- (\ x y -> x >>= \ x' -> y >>= \ y' -> return $ And [x', y'])- id- range''' >>= return . Just- where- -- Choose the simpler of the two- range''' = canon (simpler range' range'')- -- Unrestrict the range for versions that we know don't exist for this debian package- range'' = canon (unionVersionRanges range' (invertVersionRange range))- -- Restrict the range to the versions specified for this debian package- range' = intersectVersionRanges cabalRange' range- -- When we see a cabal equals dependency we need to turn it into- -- a wildcard because the resulting debian version numbers have- -- various suffixes added.- cabalRange' =- foldVersionRange'- anyVersion- withinVersion -- <- Here we are turning equals into wildcard- laterVersion- earlierVersion- orLaterVersion- orEarlierVersion- (\ lb ub -> intersectVersionRanges (orLaterVersion lb) (earlierVersion ub))- unionVersionRanges- intersectVersionRanges- id- cabalRange- simpler v1 v2 = minimumBy (compare `on` (length . asVersionIntervals)) [v1, v2]- -- Simplify a VersionRange- canon = fromVersionIntervals . toVersionIntervals---- If a package is bundled with the compiler we make the--- compiler a substitute for that package. If we were to--- specify the virtual package (e.g. libghc-base-dev) we would--- have to make sure not to specify a version number.-doBundled :: Monad m => B.PackageType -> PackageName -> [D.Relation] -> DebT m [D.Relation]-doBundled typ name rels =- do comp <- access T.compiler >>= return . fromMaybe (error "no Compiler value")- case ghcBuiltIn comp name of- True -> return $ rels ++ [D.Rel (compilerPackageName typ) Nothing Nothing]- False -> return rels- where- compilerPackageName B.Documentation = D.BinPkgName "ghc-doc"- compilerPackageName B.Profiling = D.BinPkgName "ghc-prof"- compilerPackageName B.Development = D.BinPkgName "ghc"- compilerPackageName _ = D.BinPkgName "ghc" -- whatevs---- Convert a cabal version to a debian version, adding an epoch number if requested-debianVersion' :: Monad m => PackageName -> Version -> DebT m DebianVersion-debianVersion' name v =- do atoms <- get- return $ parseDebianVersion (maybe "" (\ n -> show n ++ ":") (Map.lookup name (getL T.epochMap atoms)) ++ showVersion v)--data Rels a = And {unAnd :: [Rels a]} | Or {unOr :: [Rels a]} | Rel' {unRel :: a} deriving Show--convert' :: Rels a -> [[a]]-convert' = List.map (List.map unRel . unOr) . unAnd . canonical---- | return and of ors of rel-canonical :: Rels a -> Rels a-canonical (Rel' rel) = And [Or [Rel' rel]]-canonical (And rels) = And $ concatMap (unAnd . canonical) rels-canonical (Or rels) = And . List.map Or $ sequence $ List.map (concat . List.map unOr . unAnd . canonical) $ rels--filterMissing :: Monad m => [[Relation]] -> DebT m [[Relation]]-filterMissing rels =- get >>= \ atoms -> return $- List.filter (/= []) (List.map (List.filter (\ (Rel name _ _) -> not (Set.member name (getL T.missingDependencies atoms)))) rels)
src/Debian/Debianize/Types.hs view
@@ -65,7 +65,6 @@ , debianDescription , essential - , relations , depends , recommends , suggests@@ -136,9 +135,12 @@ -- file, for a debian package it would contain the debian directory. newtype Top = Top {unTop :: FilePath} deriving (Eq, Ord, Show, Typeable) +-- | Not exported - <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Package> binaryDebDescription :: BinPkgName -> Lens Atoms B.BinaryDebDescription binaryDebDescription b = maybeLens (B.newBinaryDebDescription b) (iso id id) . listElemLens ((== b) . getL B.package) . S.binaryPackages . control +-- | Lens onto one of several 'B.PackageType' values of which we have+-- specific knowledge how to package. packageType :: BinPkgName -> Lens Atoms (Maybe B.PackageType) packageType b = B.packageType . binaryDebDescription b @@ -146,49 +148,53 @@ debianDescription :: BinPkgName -> Lens Atoms (Maybe Text) debianDescription b = B.description . binaryDebDescription b +-- | <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Essential> essential :: BinPkgName -> Lens Atoms (Maybe Bool) essential b = B.essential . binaryDebDescription b +-- | <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s5.6.10> relations :: BinPkgName -> Lens Atoms B.PackageRelations relations b = B.relations . binaryDebDescription b --- | The Depends: relations for each binary deb.+-- | The Depends: relations for each binary deb - <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s5.6.10> depends :: BinPkgName -> Lens Atoms Relations depends b = B.depends . B.relations . binaryDebDescription b --- | The Recommends: relations for each binary deb.+-- | The Recommends: relations for each binary deb - <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s5.6.10> recommends :: BinPkgName -> Lens Atoms Relations recommends b = B.recommends . B.relations . binaryDebDescription b --- | The Suggests: relations for each binary deb.+-- | The Suggests: relations for each binary deb - <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s5.6.10> suggests :: BinPkgName -> Lens Atoms Relations suggests b = B.suggests . B.relations . binaryDebDescription b --- | The Pre-Depends: relations for each binary deb.+-- | The Pre-Depends: relations for each binary deb - <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s5.6.10> preDepends :: BinPkgName -> Lens Atoms Relations preDepends b = B.preDepends . B.relations . binaryDebDescription b --- | The Breaks: relations for each binary deb.+-- | The Breaks: relations for each binary deb - <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s5.6.10> breaks :: BinPkgName -> Lens Atoms Relations breaks b = B.breaks . B.relations . binaryDebDescription b --- | The Conflicts: relations for each binary deb.+-- | The Conflicts: relations for each binary deb - <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s5.6.10> conflicts :: BinPkgName -> Lens Atoms Relations conflicts b = B.conflicts . B.relations . binaryDebDescription b --- | The Provides: relations for each binary deb.+-- | The Provides: relations for each binary deb - <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s5.6.10> provides :: BinPkgName -> Lens Atoms Relations provides b = B.provides . B.relations . binaryDebDescription b --- | The Replaces: relations for each binary deb.+-- | The Replaces: relations for each binary deb - <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s5.6.10> replaces :: BinPkgName -> Lens Atoms Relations replaces b = B.replaces . B.relations . binaryDebDescription b +-- | THe Built-Using: relations for each binary deb - <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s5.6.10> builtUsing :: BinPkgName -> Lens Atoms Relations builtUsing b = B.builtUsing . B.relations . binaryDebDescription b -- | Maintainer field. Overrides any value found in the cabal file, or -- in the DEBIANMAINTAINER environment variable.+-- <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Maintainer> maintainer :: Lens Atoms (Maybe NameAddr) maintainer = S.maintainer . control @@ -196,7 +202,7 @@ binaryArchitectures :: BinPkgName -> Lens Atoms (Maybe PackageArchitectures) binaryArchitectures b = B.architecture . binaryDebDescription b --- | The source package priority+-- | The source package priority - <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Priority> sourcePriority :: Lens Atoms (Maybe PackagePriority) sourcePriority = S.priority . control @@ -204,7 +210,7 @@ binaryPriority :: BinPkgName -> Lens Atoms (Maybe PackagePriority) binaryPriority b = B.binaryPriority . binaryDebDescription b --- | The source package's section assignment+-- | The source package's section assignment - <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Section> sourceSection :: Lens Atoms (Maybe Section) sourceSection = S.section . control @@ -214,40 +220,51 @@ -- * Debian dependency info +-- | <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Source> source :: Lens Atoms (Maybe SrcPkgName) source = S.source . control +-- | <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Changed-By> changedBy :: Lens Atoms (Maybe NameAddr) changedBy = S.changedBy . control +-- | <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Uploaders> uploaders :: Lens Atoms ([NameAddr]) uploaders = S.uploaders . control +-- | Obsolete - <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-DM-Upload-Allowed> dmUploadAllowed :: Lens Atoms (Bool) dmUploadAllowed = S.dmUploadAllowed . control --- | The @Standards-Version@ field of the @debian/control@ file+-- | The @Standards-Version@ field of the @debian/control@ file - <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Standards-Version> standardsVersion :: Lens Atoms (Maybe StandardsVersion) standardsVersion = S.standardsVersion . control +-- | <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Homepage> homepage :: Lens Atoms (Maybe Text) homepage = S.homepage . control +-- | Version control system field - <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-VCS-fields> vcsFields :: Lens Atoms (Set S.VersionControlSpec) vcsFields = S.vcsFields . control +-- | User defined fields - <http://www.debian.org/doc/debian-policy/ch-controlfields.html#s5.7> xFields :: Lens Atoms (Set S.XField) xFields = S.xFields . control +-- | <http://www.debian.org/doc/debian-policy/ch-relationships.html#s-sourcebinarydeps> buildDepends :: Lens Atoms Relations buildDepends = S.buildDepends . control +-- | <http://www.debian.org/doc/debian-policy/ch-relationships.html#s-sourcebinarydeps> buildDependsIndep :: Lens Atoms Relations buildDependsIndep = S.buildDependsIndep . control +-- | <http://www.debian.org/doc/debian-policy/ch-relationships.html#s-sourcebinarydeps> buildConflicts :: Lens Atoms Relations buildConflicts = S.buildConflicts . control +-- | <http://www.debian.org/doc/debian-policy/ch-relationships.html#s-sourcebinarydeps> buildConflictsIndep :: Lens Atoms Relations buildConflictsIndep = S.buildConflictsIndep . control
src/Debian/Orphans.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, OverloadedStrings, StandaloneDeriving #-}+{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, OverloadedStrings, StandaloneDeriving, CPP #-} {-# OPTIONS_GHC -Wall -fno-warn-orphans #-} module Debian.Orphans where @@ -24,17 +24,23 @@ deriving instance Typeable Compiler deriving instance Typeable CompilerId++#if !MIN_VERSION_Cabal(1,18,0) deriving instance Typeable CompilerFlavor deriving instance Typeable Language deriving instance Typeable Extension deriving instance Typeable KnownExtension+#endif +deriving instance Data Compiler+deriving instance Data CompilerId++#if !MIN_VERSION_Cabal(1,18,0) deriving instance Data Extension deriving instance Data KnownExtension deriving instance Data Language-deriving instance Data Compiler-deriving instance Data CompilerId deriving instance Data CompilerFlavor+#endif deriving instance Ord Language deriving instance Ord KnownExtension@@ -101,9 +107,11 @@ pretty (BinPkgName x) = pretty x -} +#if !MIN_VERSION_Cabal(1,18,0) deriving instance Typeable License deriving instance Data Version deriving instance Data License+#endif -- Convert from license to RPM-friendly description. The strings are -- taken from TagsCheck.py in the rpmlint distribution.