-- | Compute the debianization of a cabal package.
{-# LANGUAGE CPP, OverloadedStrings, ScopedTypeVariables, TupleSections #-}
module Debian.Debianize.BuildDependencies
    ( debianBuildDeps
    , debianBuildDepsIndep
    ) where


import Control.Lens
import Control.Monad ((>=>))
import Control.Monad.IO.Class (liftIO)
import Control.Monad.State (MonadState(get))
import Control.Monad.Trans (MonadIO)
import Data.Char (isSpace, toLower)
import Data.Function (on)
import Data.List as List (filter, groupBy, map, minimumBy, nub, sortBy)
import Data.Map as Map (lookup, Map)
import Data.Maybe (catMaybes, fromMaybe, isJust, isNothing, listToMaybe, mapMaybe, maybeToList)
import Data.Set as Set (empty, fold, fromList, map, member, Set, singleton, toList, union)
import Debian.Debianize.Prelude
import Debian.Debianize.BasicInfo (compilerFlavor)
import Debian.Debianize.Bundled (builtIn)
import qualified Debian.Debianize.DebInfo as D
import Debian.Debianize.DebianName (mkPkgName, mkPkgName')
import Debian.Debianize.Monad as Monad (CabalInfo, CabalT)
import qualified Debian.Debianize.BinaryDebDescription as B
import qualified Debian.Debianize.CabalInfo as A
import qualified Debian.Debianize.SourceDebDescription as S
import Debian.Debianize.VersionSplits (packageRangesFromVersionSplits)
import Debian.GHC (compilerPackageName)
import Debian.Orphans ()
import Debian.Relation (BinPkgName(..), checkVersionReq, 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.Compiler (CompilerFlavor(..))
import Distribution.Package (Dependency(..), PackageIdentifier(pkgName, pkgVersion), PackageName)
import Distribution.PackageDescription as Cabal (BuildInfo(..), BuildInfo(buildTools, extraLibs, pkgconfigDepends), Library(..), Executable(..), TestSuite(..), SetupBuildInfo(..), PackageDescription(setupBuildInfo))
import qualified Distribution.PackageDescription as Cabal (PackageDescription(library, executables, testSuites))
import Distribution.Pretty (prettyShow)
import Distribution.Types.LegacyExeDependency (LegacyExeDependency(..))
#if MIN_VERSION_Cabal(3,4,0)
import qualified Distribution.Compat.NonEmptySet as NES
import Distribution.Types.LibraryName (defaultLibName)
import Distribution.Version (anyVersion, asVersionIntervals, fromVersionIntervals, intersectVersionRanges, isNoVersion, toVersionIntervals, unionVersionRanges, VersionRange, withinVersion)
#else
import Distribution.Version (anyVersion, asVersionIntervals, fromVersionIntervals, intersectVersionRanges, invertVersionRange, isNoVersion, toVersionIntervals, unionVersionRanges, VersionRange, withinVersion)
#endif
import Distribution.Types.PkgconfigDependency (PkgconfigDependency(..))
import Prelude hiding (init, log, map, unlines, unlines, writeFile)
import System.Directory (findExecutable)
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 (Dependency_ -> Dependency_ -> Bool
(Dependency_ -> Dependency_ -> Bool)
-> (Dependency_ -> Dependency_ -> Bool) -> Eq Dependency_
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Dependency_ -> Dependency_ -> Bool
$c/= :: Dependency_ -> Dependency_ -> Bool
== :: Dependency_ -> Dependency_ -> Bool
$c== :: Dependency_ -> Dependency_ -> Bool
Eq, Int -> Dependency_ -> ShowS
[Dependency_] -> ShowS
Dependency_ -> String
(Int -> Dependency_ -> ShowS)
-> (Dependency_ -> String)
-> ([Dependency_] -> ShowS)
-> Show Dependency_
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Dependency_] -> ShowS
$cshowList :: [Dependency_] -> ShowS
show :: Dependency_ -> String
$cshow :: Dependency_ -> String
showsPrec :: Int -> Dependency_ -> ShowS
$cshowsPrec :: Int -> Dependency_ -> ShowS
Show)

-- | Naive conversion of Cabal build dependencies to Debian
-- dependencies will usually result in a self dependency, due to the
-- fact that a Cabal executable often depends on the associated
-- library to build.  Due to the fact that Debian build dependencies
-- are global to the package, this results in unwanted self
-- dependencies, which usually need to be filtered out.
-- Unfortunately, some Debian packages actually do depend on an
-- earlier version of themselves to build (e.g. most compilers.)  So a
-- command line option is probably necessary.
--
-- selfDependency :: PackageIdentifier -> Dependency_ -> Bool
-- selfDependency pkgId (BuildDepends (Dependency name _)) = name == pkgName pkgId
-- selfDependency _ _ = False

unboxDependency :: Dependency_ -> Maybe Dependency
unboxDependency :: Dependency_ -> Maybe Dependency
unboxDependency (BuildDepends Dependency
d) = Dependency -> Maybe Dependency
forall a. a -> Maybe a
Just Dependency
d
unboxDependency (BuildTools Dependency
d) = Dependency -> Maybe Dependency
forall a. a -> Maybe a
Just Dependency
d
unboxDependency (PkgConfigDepends Dependency
d) = Dependency -> Maybe Dependency
forall a. a -> Maybe a
Just Dependency
d
unboxDependency (ExtraLibs Relations
_) = Maybe Dependency
forall a. Maybe a
Nothing -- Dependency (PackageName d) anyVersion mempty

-- |Debian packages don't have per binary package build dependencies,
-- so we just gather them all up here.
allBuildDepends :: Monad m => [BuildInfo] -> CabalT m [Dependency_]
allBuildDepends :: [BuildInfo] -> CabalT m [Dependency_]
allBuildDepends [BuildInfo]
buildInfos =
    [Dependency]
-> [Dependency]
-> [Dependency]
-> [String]
-> CabalT m [Dependency_]
forall (m :: * -> *).
Monad m =>
[Dependency]
-> [Dependency]
-> [Dependency]
-> [String]
-> CabalT m [Dependency_]
allBuildDepends'
      ([Dependency] -> [Dependency]
mergeCabalDependencies ([Dependency] -> [Dependency]) -> [Dependency] -> [Dependency]
forall a b. (a -> b) -> a -> b
$ (BuildInfo -> [Dependency]) -> [BuildInfo] -> [Dependency]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap BuildInfo -> [Dependency]
Cabal.targetBuildDepends [BuildInfo]
buildInfos)
      ([Dependency] -> [Dependency]
mergeCabalDependencies ([Dependency] -> [Dependency]) -> [Dependency] -> [Dependency]
forall a b. (a -> b) -> a -> b
$ (LegacyExeDependency -> Maybe Dependency)
-> [LegacyExeDependency] -> [Dependency]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe LegacyExeDependency -> Maybe Dependency
convertLegacy ([LegacyExeDependency] -> [Dependency])
-> [LegacyExeDependency] -> [Dependency]
forall a b. (a -> b) -> a -> b
$ (BuildInfo -> [LegacyExeDependency])
-> [BuildInfo] -> [LegacyExeDependency]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap BuildInfo -> [LegacyExeDependency]
buildTools [BuildInfo]
buildInfos)
      ([Dependency] -> [Dependency]
mergeCabalDependencies ([Dependency] -> [Dependency]) -> [Dependency] -> [Dependency]
forall a b. (a -> b) -> a -> b
$ (PkgconfigDependency -> Maybe Dependency)
-> [PkgconfigDependency] -> [Dependency]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe PkgconfigDependency -> Maybe Dependency
convertPkgconfig ([PkgconfigDependency] -> [Dependency])
-> [PkgconfigDependency] -> [Dependency]
forall a b. (a -> b) -> a -> b
$  (BuildInfo -> [PkgconfigDependency])
-> [BuildInfo] -> [PkgconfigDependency]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap BuildInfo -> [PkgconfigDependency]
pkgconfigDepends [BuildInfo]
buildInfos)
      ((BuildInfo -> [String]) -> [BuildInfo] -> [String]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap BuildInfo -> [String]
extraLibs [BuildInfo]
buildInfos)
    where
      convertLegacy :: LegacyExeDependency -> Maybe Dependency
      convertLegacy :: LegacyExeDependency -> Maybe Dependency
convertLegacy = Maybe Dependency -> LegacyExeDependency -> Maybe Dependency
forall a b. a -> b -> a
const Maybe Dependency
forall a. Maybe a
Nothing
      convertPkgconfig :: PkgconfigDependency -> Maybe Dependency
      convertPkgconfig :: PkgconfigDependency -> Maybe Dependency
convertPkgconfig = Maybe Dependency -> PkgconfigDependency -> Maybe Dependency
forall a b. a -> b -> a
const Maybe Dependency
forall a. Maybe a
Nothing
      allBuildDepends' :: Monad m => [Dependency] -> [Dependency] -> [Dependency] -> [String] -> CabalT m [Dependency_]
      allBuildDepends' :: [Dependency]
-> [Dependency]
-> [Dependency]
-> [String]
-> CabalT m [Dependency_]
allBuildDepends' [Dependency]
buildDepends' [Dependency]
buildTools' [Dependency]
pkgconfigDepends' [String]
extraLibs' =
          do CabalInfo
atoms <- StateT CabalInfo m CabalInfo
forall s (m :: * -> *). MonadState s m => m s
get
             [Dependency_] -> CabalT m [Dependency_]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Dependency_] -> CabalT m [Dependency_])
-> [Dependency_] -> CabalT m [Dependency_]
forall a b. (a -> b) -> a -> b
$ [Dependency_] -> [Dependency_]
forall a. Eq a => [a] -> [a]
nub ([Dependency_] -> [Dependency_]) -> [Dependency_] -> [Dependency_]
forall a b. (a -> b) -> a -> b
$ (Dependency -> Dependency_) -> [Dependency] -> [Dependency_]
forall a b. (a -> b) -> [a] -> [b]
List.map Dependency -> Dependency_
BuildDepends [Dependency]
buildDepends' [Dependency_] -> [Dependency_] -> [Dependency_]
forall a. [a] -> [a] -> [a]
++
                            (Dependency -> Dependency_) -> [Dependency] -> [Dependency_]
forall a b. (a -> b) -> [a] -> [b]
List.map Dependency -> Dependency_
BuildTools [Dependency]
buildTools' [Dependency_] -> [Dependency_] -> [Dependency_]
forall a. [a] -> [a] -> [a]
++
                            (Dependency -> Dependency_) -> [Dependency] -> [Dependency_]
forall a b. (a -> b) -> [a] -> [b]
List.map Dependency -> Dependency_
PkgConfigDepends [Dependency]
pkgconfigDepends' [Dependency_] -> [Dependency_] -> [Dependency_]
forall a. [a] -> [a] -> [a]
++
                            [Relations -> Dependency_
ExtraLibs (CabalInfo -> [String] -> Relations
fixDeps CabalInfo
atoms [String]
extraLibs')]

      fixDeps :: CabalInfo -> [String] -> Relations
      fixDeps :: CabalInfo -> [String] -> Relations
fixDeps CabalInfo
atoms =
          (String -> Relations) -> [String] -> Relations
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\ String
cab -> Relations -> Maybe Relations -> Relations
forall a. a -> Maybe a -> a
fromMaybe [[BinPkgName -> Maybe VersionReq -> Maybe ArchitectureReq -> Relation
D.Rel (String -> BinPkgName
D.BinPkgName (String
"lib" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Char -> Char) -> ShowS
forall a b. (a -> b) -> [a] -> [b]
List.map Char -> Char
toLower String
cab String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"-dev")) Maybe VersionReq
forall a. Maybe a
Nothing Maybe ArchitectureReq
forall a. Maybe a
Nothing]]
                                        (String -> Map String Relations -> Maybe Relations
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup String
cab (Getting (Map String Relations) CabalInfo (Map String Relations)
-> CabalInfo -> Map String Relations
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view ((DebInfo -> Const (Map String Relations) DebInfo)
-> CabalInfo -> Const (Map String Relations) CabalInfo
Lens' CabalInfo DebInfo
A.debInfo ((DebInfo -> Const (Map String Relations) DebInfo)
 -> CabalInfo -> Const (Map String Relations) CabalInfo)
-> ((Map String Relations
     -> Const (Map String Relations) (Map String Relations))
    -> DebInfo -> Const (Map String Relations) DebInfo)
-> Getting (Map String Relations) CabalInfo (Map String Relations)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Map String Relations
 -> Const (Map String Relations) (Map String Relations))
-> DebInfo -> Const (Map String Relations) DebInfo
Lens' DebInfo (Map String Relations)
D.extraLibMap) CabalInfo
atoms)))

setupBuildDepends :: SetupBuildInfo -> [Dependency_]
setupBuildDepends :: SetupBuildInfo -> [Dependency_]
setupBuildDepends = (Dependency -> Dependency_) -> [Dependency] -> [Dependency_]
forall a b. (a -> b) -> [a] -> [b]
List.map Dependency -> Dependency_
BuildDepends ([Dependency] -> [Dependency_])
-> (SetupBuildInfo -> [Dependency])
-> SetupBuildInfo
-> [Dependency_]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SetupBuildInfo -> [Dependency]
setupDepends

-- | Take the intersection of all the dependencies on a given package name
mergeCabalDependencies :: [Dependency] -> [Dependency]
mergeCabalDependencies :: [Dependency] -> [Dependency]
mergeCabalDependencies =
#if MIN_VERSION_Cabal(3,4,0)
    List.map (foldl1 (\ (Dependency name range1 _) (Dependency _ range2 _) -> Dependency name (intersectVersionRanges range1 range2) (NES.singleton defaultLibName))) . groupBy ((==) `on` dependencyPackage) . sortBy (compare `on` dependencyPackage)
#else
    ([Dependency] -> Dependency) -> [[Dependency]] -> [Dependency]
forall a b. (a -> b) -> [a] -> [b]
List.map ((Dependency -> Dependency -> Dependency)
-> [Dependency] -> Dependency
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 (\ (Dependency PackageName
name VersionRange
range1 Set LibraryName
_) (Dependency PackageName
_ VersionRange
range2 Set LibraryName
_) -> PackageName -> VersionRange -> Set LibraryName -> Dependency
Dependency PackageName
name (VersionRange -> VersionRange -> VersionRange
intersectVersionRanges VersionRange
range1 VersionRange
range2) Set LibraryName
forall a. Monoid a => a
mempty)) ([[Dependency]] -> [Dependency])
-> ([Dependency] -> [[Dependency]]) -> [Dependency] -> [Dependency]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Dependency -> Dependency -> Bool)
-> [Dependency] -> [[Dependency]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy (PackageName -> PackageName -> Bool
forall a. Eq a => a -> a -> Bool
(==) (PackageName -> PackageName -> Bool)
-> (Dependency -> PackageName) -> Dependency -> Dependency -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Dependency -> PackageName
dependencyPackage) ([Dependency] -> [[Dependency]])
-> ([Dependency] -> [Dependency]) -> [Dependency] -> [[Dependency]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Dependency -> Dependency -> Ordering)
-> [Dependency] -> [Dependency]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (PackageName -> PackageName -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (PackageName -> PackageName -> Ordering)
-> (Dependency -> PackageName)
-> Dependency
-> Dependency
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Dependency -> PackageName
dependencyPackage)
#endif
    where
      dependencyPackage :: Dependency -> PackageName
dependencyPackage (Dependency PackageName
x VersionRange
_ Set LibraryName
_) = PackageName
x

-- The haskell-devscripts-minimal package contains the hlibrary.mk file with
-- the rules for building haskell packages.
debianBuildDeps :: (MonadIO m) => PackageDescription -> CabalT m D.Relations
debianBuildDeps :: PackageDescription -> CabalT m Relations
debianBuildDeps PackageDescription
pkgDesc =
    do CompilerFlavor
hflavor <- Getting CompilerFlavor CabalInfo CompilerFlavor
-> StateT CabalInfo m CompilerFlavor
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((DebInfo -> Const CompilerFlavor DebInfo)
-> CabalInfo -> Const CompilerFlavor CabalInfo
Lens' CabalInfo DebInfo
A.debInfo ((DebInfo -> Const CompilerFlavor DebInfo)
 -> CabalInfo -> Const CompilerFlavor CabalInfo)
-> ((CompilerFlavor -> Const CompilerFlavor CompilerFlavor)
    -> DebInfo -> Const CompilerFlavor DebInfo)
-> Getting CompilerFlavor CabalInfo CompilerFlavor
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Flags -> Const CompilerFlavor Flags)
-> DebInfo -> Const CompilerFlavor DebInfo
Lens' DebInfo Flags
D.flags ((Flags -> Const CompilerFlavor Flags)
 -> DebInfo -> Const CompilerFlavor DebInfo)
-> ((CompilerFlavor -> Const CompilerFlavor CompilerFlavor)
    -> Flags -> Const CompilerFlavor Flags)
-> (CompilerFlavor -> Const CompilerFlavor CompilerFlavor)
-> DebInfo
-> Const CompilerFlavor DebInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CompilerFlavor -> Const CompilerFlavor CompilerFlavor)
-> Flags -> Const CompilerFlavor Flags
Lens' Flags CompilerFlavor
compilerFlavor)
       Bool
prof <- Bool -> Bool
not (Bool -> Bool)
-> StateT CabalInfo m Bool -> StateT CabalInfo m Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Getting Bool CabalInfo Bool -> StateT CabalInfo m Bool
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((DebInfo -> Const Bool DebInfo)
-> CabalInfo -> Const Bool CabalInfo
Lens' CabalInfo DebInfo
A.debInfo ((DebInfo -> Const Bool DebInfo)
 -> CabalInfo -> Const Bool CabalInfo)
-> ((Bool -> Const Bool Bool) -> DebInfo -> Const Bool DebInfo)
-> Getting Bool CabalInfo Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Const Bool Bool) -> DebInfo -> Const Bool DebInfo
Lens' DebInfo Bool
D.noProfilingLibrary)
       let hcPackageTypes :: CompilerFlavor -> Set B.PackageType
           hcPackageTypes :: CompilerFlavor -> Set PackageType
hcPackageTypes CompilerFlavor
GHC = [PackageType] -> Set PackageType
forall a. Ord a => [a] -> Set a
fromList ([PackageType
B.Development] [PackageType] -> [PackageType] -> [PackageType]
forall a. Semigroup a => a -> a -> a
<> if Bool
prof then [PackageType
B.Profiling] else [])
           hcPackageTypes CompilerFlavor
GHCJS = [PackageType] -> Set PackageType
forall a. Ord a => [a] -> Set a
fromList [PackageType
B.Development]
           hcPackageTypes CompilerFlavor
hc = String -> Set PackageType
forall a. HasCallStack => String -> a
error (String -> Set PackageType) -> String -> Set PackageType
forall a b. (a -> b) -> a -> b
$ String
"Unsupported compiler flavor: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ CompilerFlavor -> String
forall a. Show a => a -> String
show CompilerFlavor
hc

       let hcs :: Set CompilerFlavor
hcs = CompilerFlavor -> Set CompilerFlavor
forall a. a -> Set a
singleton CompilerFlavor
hflavor -- vestigial
           hcTypePairs :: Set (CompilerFlavor, PackageType)
hcTypePairs =
               (Set (CompilerFlavor, PackageType)
 -> Set (CompilerFlavor, PackageType)
 -> Set (CompilerFlavor, PackageType))
-> Set (CompilerFlavor, PackageType)
-> Set (Set (CompilerFlavor, PackageType))
-> Set (CompilerFlavor, PackageType)
forall a b. (a -> b -> b) -> b -> Set a -> b
fold Set (CompilerFlavor, PackageType)
-> Set (CompilerFlavor, PackageType)
-> Set (CompilerFlavor, PackageType)
forall a. Ord a => Set a -> Set a -> Set a
union Set (CompilerFlavor, PackageType)
forall a. Set a
empty (Set (Set (CompilerFlavor, PackageType))
 -> Set (CompilerFlavor, PackageType))
-> Set (Set (CompilerFlavor, PackageType))
-> Set (CompilerFlavor, PackageType)
forall a b. (a -> b) -> a -> b
$
                  (CompilerFlavor -> Set (CompilerFlavor, PackageType))
-> Set CompilerFlavor -> Set (Set (CompilerFlavor, PackageType))
forall b a. Ord b => (a -> b) -> Set a -> Set b
Set.map (\ CompilerFlavor
hc' -> (PackageType -> (CompilerFlavor, PackageType))
-> Set PackageType -> Set (CompilerFlavor, PackageType)
forall b a. Ord b => (a -> b) -> Set a -> Set b
Set.map (CompilerFlavor
hc',) (Set PackageType -> Set (CompilerFlavor, PackageType))
-> Set PackageType -> Set (CompilerFlavor, PackageType)
forall a b. (a -> b) -> a -> b
$ CompilerFlavor -> Set PackageType
hcPackageTypes CompilerFlavor
hc') Set CompilerFlavor
hcs
           setupDeps :: [Dependency_]
setupDeps = [[Dependency_]] -> [Dependency_]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Dependency_]] -> [Dependency_])
-> (PackageDescription -> [[Dependency_]])
-> PackageDescription
-> [Dependency_]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe [Dependency_] -> [[Dependency_]]
forall a. Maybe a -> [a]
maybeToList (Maybe [Dependency_] -> [[Dependency_]])
-> (PackageDescription -> Maybe [Dependency_])
-> PackageDescription
-> [[Dependency_]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SetupBuildInfo -> [Dependency_])
-> Maybe SetupBuildInfo -> Maybe [Dependency_]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SetupBuildInfo -> [Dependency_]
setupBuildDepends (Maybe SetupBuildInfo -> Maybe [Dependency_])
-> (PackageDescription -> Maybe SetupBuildInfo)
-> PackageDescription
-> Maybe [Dependency_]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageDescription -> Maybe SetupBuildInfo
setupBuildInfo (PackageDescription -> [Dependency_])
-> PackageDescription -> [Dependency_]
forall a b. (a -> b) -> a -> b
$ PackageDescription
pkgDesc

       [Dependency_]
libDeps <- [BuildInfo] -> CabalT m [Dependency_]
forall (m :: * -> *).
Monad m =>
[BuildInfo] -> CabalT m [Dependency_]
allBuildDepends ([BuildInfo]
-> (Library -> [BuildInfo]) -> Maybe Library -> [BuildInfo]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] ((BuildInfo -> Bool) -> [BuildInfo] -> [BuildInfo]
forall a. (a -> Bool) -> [a] -> [a]
filter BuildInfo -> Bool
forall e. IsBuildable e => e -> Bool
isBuildable ([BuildInfo] -> [BuildInfo])
-> (Library -> [BuildInfo]) -> Library -> [BuildInfo]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BuildInfo -> [BuildInfo]
forall (m :: * -> *) a. Monad m => a -> m a
return (BuildInfo -> [BuildInfo])
-> (Library -> BuildInfo) -> Library -> [BuildInfo]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Library -> BuildInfo
libBuildInfo) (PackageDescription -> Maybe Library
Cabal.library PackageDescription
pkgDesc))
       [Dependency_]
binDeps <- [BuildInfo] -> CabalT m [Dependency_]
forall (m :: * -> *).
Monad m =>
[BuildInfo] -> CabalT m [Dependency_]
allBuildDepends ((Executable -> BuildInfo) -> [Executable] -> [BuildInfo]
forall a b. (a -> b) -> [a] -> [b]
List.map Executable -> BuildInfo
buildInfo ((Executable -> Bool) -> [Executable] -> [Executable]
forall a. (a -> Bool) -> [a] -> [a]
filter Executable -> Bool
forall e. IsBuildable e => e -> Bool
isBuildable (PackageDescription -> [Executable]
Cabal.executables PackageDescription
pkgDesc)))
       [Dependency_]
testDeps <- [BuildInfo] -> CabalT m [Dependency_]
forall (m :: * -> *).
Monad m =>
[BuildInfo] -> CabalT m [Dependency_]
allBuildDepends ((TestSuite -> BuildInfo) -> [TestSuite] -> [BuildInfo]
forall a b. (a -> b) -> [a] -> [b]
List.map TestSuite -> BuildInfo
testBuildInfo ((TestSuite -> Bool) -> [TestSuite] -> [TestSuite]
forall a. (a -> Bool) -> [a] -> [a]
filter TestSuite -> Bool
forall e. IsBuildable e => e -> Bool
isBuildable (PackageDescription -> [TestSuite]
Cabal.testSuites PackageDescription
pkgDesc)))
       TestsStatus
testsStatus <- Getting TestsStatus CabalInfo TestsStatus
-> StateT CabalInfo m TestsStatus
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((DebInfo -> Const TestsStatus DebInfo)
-> CabalInfo -> Const TestsStatus CabalInfo
Lens' CabalInfo DebInfo
A.debInfo ((DebInfo -> Const TestsStatus DebInfo)
 -> CabalInfo -> Const TestsStatus CabalInfo)
-> ((TestsStatus -> Const TestsStatus TestsStatus)
    -> DebInfo -> Const TestsStatus DebInfo)
-> Getting TestsStatus CabalInfo TestsStatus
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TestsStatus -> Const TestsStatus TestsStatus)
-> DebInfo -> Const TestsStatus DebInfo
Lens' DebInfo TestsStatus
D.testsStatus)

       Relations
cDeps <- Relations -> Relations
forall a. Eq a => [a] -> [a]
nub (Relations -> Relations)
-> ([[Relations]] -> Relations) -> [[Relations]] -> Relations
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Relations] -> Relations
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([Relations] -> Relations)
-> ([[Relations]] -> [Relations]) -> [[Relations]] -> Relations
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Relations]] -> [Relations]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Relations]] -> Relations)
-> StateT CabalInfo m [[Relations]] -> CabalT m Relations
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [StateT CabalInfo m [Relations]]
-> StateT CabalInfo m [[Relations]]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence
            [ (Dependency_ -> CabalT m Relations)
-> [Dependency_] -> StateT CabalInfo m [Relations]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Set (CompilerFlavor, PackageType)
-> Dependency_ -> CabalT m Relations
forall (m :: * -> *).
MonadIO m =>
Set (CompilerFlavor, PackageType)
-> Dependency_ -> CabalT m Relations
buildDependencies Set (CompilerFlavor, PackageType)
hcTypePairs) [Dependency_]
libDeps
            , (Dependency_ -> CabalT m Relations)
-> [Dependency_] -> StateT CabalInfo m [Relations]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Set (CompilerFlavor, PackageType)
-> Dependency_ -> CabalT m Relations
forall (m :: * -> *).
MonadIO m =>
Set (CompilerFlavor, PackageType)
-> Dependency_ -> CabalT m Relations
buildDependencies Set (CompilerFlavor, PackageType)
hcTypePairs) [Dependency_]
binDeps
            , (Dependency_ -> CabalT m Relations)
-> [Dependency_] -> StateT CabalInfo m [Relations]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Set (CompilerFlavor, PackageType)
-> Dependency_ -> CabalT m Relations
forall (m :: * -> *).
MonadIO m =>
Set (CompilerFlavor, PackageType)
-> Dependency_ -> CabalT m Relations
buildDependencies Set (CompilerFlavor, PackageType)
hcTypePairs) [Dependency_]
setupDeps
            , (Dependency_ -> CabalT m Relations)
-> [Dependency_] -> StateT CabalInfo m [Relations]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Set (CompilerFlavor, PackageType)
-> Dependency_ -> CabalT m Relations
forall (m :: * -> *).
MonadIO m =>
Set (CompilerFlavor, PackageType)
-> Dependency_ -> CabalT m Relations
buildDependencies Set (CompilerFlavor, PackageType)
hcTypePairs) (if TestsStatus
testsStatus TestsStatus -> TestsStatus -> Bool
forall a. Eq a => a -> a -> Bool
/= TestsStatus
D.TestsDisable then [Dependency_]
testDeps else [])
            ]

       Relations
bDeps <- Getting Relations CabalInfo Relations -> CabalT m Relations
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((DebInfo -> Const Relations DebInfo)
-> CabalInfo -> Const Relations CabalInfo
Lens' CabalInfo DebInfo
A.debInfo ((DebInfo -> Const Relations DebInfo)
 -> CabalInfo -> Const Relations CabalInfo)
-> ((Relations -> Const Relations Relations)
    -> DebInfo -> Const Relations DebInfo)
-> Getting Relations CabalInfo Relations
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SourceDebDescription -> Const Relations SourceDebDescription)
-> DebInfo -> Const Relations DebInfo
Lens' DebInfo SourceDebDescription
D.control ((SourceDebDescription -> Const Relations SourceDebDescription)
 -> DebInfo -> Const Relations DebInfo)
-> ((Relations -> Const Relations Relations)
    -> SourceDebDescription -> Const Relations SourceDebDescription)
-> (Relations -> Const Relations Relations)
-> DebInfo
-> Const Relations DebInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Relations -> Const Relations Relations)
-> SourceDebDescription -> Const Relations SourceDebDescription
Lens' SourceDebDescription Relations
S.buildDepends)
       Maybe Int
compat <- Getting (Maybe Int) CabalInfo (Maybe Int)
-> StateT CabalInfo m (Maybe Int)
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((DebInfo -> Const (Maybe Int) DebInfo)
-> CabalInfo -> Const (Maybe Int) CabalInfo
Lens' CabalInfo DebInfo
A.debInfo ((DebInfo -> Const (Maybe Int) DebInfo)
 -> CabalInfo -> Const (Maybe Int) CabalInfo)
-> ((Maybe Int -> Const (Maybe Int) (Maybe Int))
    -> DebInfo -> Const (Maybe Int) DebInfo)
-> Getting (Maybe Int) CabalInfo (Maybe Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe Int -> Const (Maybe Int) (Maybe Int))
-> DebInfo -> Const (Maybe Int) DebInfo
Lens' DebInfo (Maybe Int)
D.compat)
       Maybe BinPkgName
ghcdev <- IO (Maybe BinPkgName) -> StateT CabalInfo m (Maybe BinPkgName)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe BinPkgName) -> StateT CabalInfo m (Maybe BinPkgName))
-> IO (Maybe BinPkgName) -> StateT CabalInfo m (Maybe BinPkgName)
forall a b. (a -> b) -> a -> b
$ CompilerFlavor -> PackageType -> IO (Maybe BinPkgName)
compilerPackageName CompilerFlavor
hflavor PackageType
B.Development
       Maybe BinPkgName
ghcprof <- IO (Maybe BinPkgName) -> StateT CabalInfo m (Maybe BinPkgName)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe BinPkgName) -> StateT CabalInfo m (Maybe BinPkgName))
-> IO (Maybe BinPkgName) -> StateT CabalInfo m (Maybe BinPkgName)
forall a b. (a -> b) -> a -> b
$ CompilerFlavor -> PackageType -> IO (Maybe BinPkgName)
compilerPackageName CompilerFlavor
hflavor PackageType
B.Profiling
       let ghcrel :: Relations
ghcrel = if CompilerFlavor -> Set CompilerFlavor -> Bool
forall a. Ord a => a -> Set a -> Bool
member CompilerFlavor
GHC Set CompilerFlavor
hcs then Relations
-> (BinPkgName -> Relations) -> Maybe BinPkgName -> Relations
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (([Relation] -> Relations -> Relations
forall a. a -> [a] -> [a]
: []) ([Relation] -> Relations)
-> (BinPkgName -> [Relation]) -> BinPkgName -> Relations
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BinPkgName -> [Relation]
anyrel') Maybe BinPkgName
ghcdev else []
       let ghcrelprof :: Relations
ghcrelprof = if Bool
prof then Relations
-> (BinPkgName -> Relations) -> Maybe BinPkgName -> Relations
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (([Relation] -> Relations -> Relations
forall a. a -> [a] -> [a]
: []) ([Relation] -> Relations)
-> (BinPkgName -> [Relation]) -> BinPkgName -> Relations
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BinPkgName -> [Relation]
anyrel') Maybe BinPkgName
ghcprof else []
       let xs :: Relations
xs = Relations -> Relations
forall a. Eq a => [a] -> [a]
nub (Relations -> Relations) -> Relations -> Relations
forall a b. (a -> b) -> a -> b
$ [[Relation] -> (Int -> [Relation]) -> Maybe Int -> [Relation]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\ Int
n -> [BinPkgName -> Maybe VersionReq -> Maybe ArchitectureReq -> Relation
D.Rel (String -> BinPkgName
D.BinPkgName String
"debhelper") (VersionReq -> Maybe VersionReq
forall a. a -> Maybe a
Just (DebianVersion -> VersionReq
D.GRE (String -> DebianVersion
forall string. ParseDebianVersion string => string -> DebianVersion
parseDebianVersion' (Int -> String
forall a. Show a => a -> String
show Int
n)))) Maybe ArchitectureReq
forall a. Maybe a
Nothing]) Maybe Int
compat,
                       [BinPkgName -> Maybe VersionReq -> Maybe ArchitectureReq -> Relation
D.Rel (String -> BinPkgName
D.BinPkgName String
"haskell-devscripts-minimal") Maybe VersionReq
forall a. Maybe a
Nothing Maybe ArchitectureReq
forall a. Maybe a
Nothing,
                        BinPkgName -> Maybe VersionReq -> Maybe ArchitectureReq -> Relation
D.Rel (String -> BinPkgName
D.BinPkgName String
"haskell-devscripts") (VersionReq -> Maybe VersionReq
forall a. a -> Maybe a
Just (VersionReq -> Maybe VersionReq) -> VersionReq -> Maybe VersionReq
forall a b. (a -> b) -> a -> b
$ DebianVersion -> VersionReq
D.GRE (DebianVersion -> VersionReq) -> DebianVersion -> VersionReq
forall a b. (a -> b) -> a -> b
$ String -> DebianVersion
forall string. ParseDebianVersion string => string -> DebianVersion
parseDebianVersion' (String
"0.13" :: String)) Maybe ArchitectureReq
forall a. Maybe a
Nothing],
                       String -> [Relation]
anyrel String
"cdbs"] Relations -> Relations -> Relations
forall a. [a] -> [a] -> [a]
++
                      (Relations
ghcrel Relations -> Relations -> Relations
forall a. [a] -> [a] -> [a]
++ Relations
ghcrelprof) Relations -> Relations -> Relations
forall a. [a] -> [a] -> [a]
++
                       Relations
bDeps Relations -> Relations -> Relations
forall a. [a] -> [a] -> [a]
++
                       Relations
cDeps
       Relations -> CabalT m Relations
forall (m :: * -> *). Monad m => Relations -> CabalT m Relations
filterMissing Relations
xs
    where
      -- No point in installing profiling packages for the
      -- dependencies of binaries and test suites.  (I take it back,
      -- some executable builds fail if the profiling library isn't
      -- installed.)
#if 0
      hcPackageTypesBins :: CompilerFlavor -> Set B.PackageType
      hcPackageTypesBins GHC = singleton [B.Development, B.Profiling]

      hcPackageTypesTests :: CompilerFlavor -> Set B.PackageType
      hcPackageTypesTests GHC = singleton [B.Development, B.Profiling]
#endif

class IsBuildable e where
    isBuildable :: e -> Bool

instance IsBuildable Executable where
    isBuildable :: Executable -> Bool
isBuildable = BuildInfo -> Bool
buildable (BuildInfo -> Bool)
-> (Executable -> BuildInfo) -> Executable -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Executable -> BuildInfo
buildInfo

instance IsBuildable BuildInfo where
    isBuildable :: BuildInfo -> Bool
isBuildable = BuildInfo -> Bool
buildable

instance IsBuildable TestSuite where
    isBuildable :: TestSuite -> Bool
isBuildable = BuildInfo -> Bool
buildable (BuildInfo -> Bool)
-> (TestSuite -> BuildInfo) -> TestSuite -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TestSuite -> BuildInfo
testBuildInfo

-- | Collect the dependencies required to build any packages that have
-- architecture "all".
debianBuildDepsIndep :: (MonadIO m) => PackageDescription -> CabalT m D.Relations
debianBuildDepsIndep :: PackageDescription -> CabalT m Relations
debianBuildDepsIndep PackageDescription
pkgDesc =
    do CompilerFlavor
hc <- Getting CompilerFlavor CabalInfo CompilerFlavor
-> StateT CabalInfo m CompilerFlavor
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((DebInfo -> Const CompilerFlavor DebInfo)
-> CabalInfo -> Const CompilerFlavor CabalInfo
Lens' CabalInfo DebInfo
A.debInfo ((DebInfo -> Const CompilerFlavor DebInfo)
 -> CabalInfo -> Const CompilerFlavor CabalInfo)
-> ((CompilerFlavor -> Const CompilerFlavor CompilerFlavor)
    -> DebInfo -> Const CompilerFlavor DebInfo)
-> Getting CompilerFlavor CabalInfo CompilerFlavor
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Flags -> Const CompilerFlavor Flags)
-> DebInfo -> Const CompilerFlavor DebInfo
Lens' DebInfo Flags
D.flags ((Flags -> Const CompilerFlavor Flags)
 -> DebInfo -> Const CompilerFlavor DebInfo)
-> ((CompilerFlavor -> Const CompilerFlavor CompilerFlavor)
    -> Flags -> Const CompilerFlavor Flags)
-> (CompilerFlavor -> Const CompilerFlavor CompilerFlavor)
-> DebInfo
-> Const CompilerFlavor DebInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CompilerFlavor -> Const CompilerFlavor CompilerFlavor)
-> Flags -> Const CompilerFlavor Flags
Lens' Flags CompilerFlavor
compilerFlavor)
       let hcs :: Set CompilerFlavor
hcs = CompilerFlavor -> Set CompilerFlavor
forall a. a -> Set a
singleton CompilerFlavor
hc -- vestigial
       Bool
doc <- Bool -> Bool
not (Bool -> Bool)
-> StateT CabalInfo m Bool -> StateT CabalInfo m Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Getting Bool CabalInfo Bool -> StateT CabalInfo m Bool
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((DebInfo -> Const Bool DebInfo)
-> CabalInfo -> Const Bool CabalInfo
Lens' CabalInfo DebInfo
A.debInfo ((DebInfo -> Const Bool DebInfo)
 -> CabalInfo -> Const Bool CabalInfo)
-> ((Bool -> Const Bool Bool) -> DebInfo -> Const Bool DebInfo)
-> Getting Bool CabalInfo Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Const Bool Bool) -> DebInfo -> Const Bool DebInfo
Lens' DebInfo Bool
D.noDocumentationLibrary)
       Relations
bDeps <- Getting Relations CabalInfo Relations -> CabalT m Relations
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((DebInfo -> Const Relations DebInfo)
-> CabalInfo -> Const Relations CabalInfo
Lens' CabalInfo DebInfo
A.debInfo ((DebInfo -> Const Relations DebInfo)
 -> CabalInfo -> Const Relations CabalInfo)
-> ((Relations -> Const Relations Relations)
    -> DebInfo -> Const Relations DebInfo)
-> Getting Relations CabalInfo Relations
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SourceDebDescription -> Const Relations SourceDebDescription)
-> DebInfo -> Const Relations DebInfo
Lens' DebInfo SourceDebDescription
D.control ((SourceDebDescription -> Const Relations SourceDebDescription)
 -> DebInfo -> Const Relations DebInfo)
-> ((Relations -> Const Relations Relations)
    -> SourceDebDescription -> Const Relations SourceDebDescription)
-> (Relations -> Const Relations Relations)
-> DebInfo
-> Const Relations DebInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Relations -> Const Relations Relations)
-> SourceDebDescription -> Const Relations SourceDebDescription
Lens' SourceDebDescription Relations
S.buildDependsIndep)
       [Dependency_]
libDeps <- [BuildInfo] -> CabalT m [Dependency_]
forall (m :: * -> *).
Monad m =>
[BuildInfo] -> CabalT m [Dependency_]
allBuildDepends ([BuildInfo]
-> (Library -> [BuildInfo]) -> Maybe Library -> [BuildInfo]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (BuildInfo -> [BuildInfo]
forall (m :: * -> *) a. Monad m => a -> m a
return (BuildInfo -> [BuildInfo])
-> (Library -> BuildInfo) -> Library -> [BuildInfo]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Library -> BuildInfo
libBuildInfo) (PackageDescription -> Maybe Library
Cabal.library PackageDescription
pkgDesc))
       [Relations]
cDeps <- (Dependency_ -> CabalT m Relations)
-> [Dependency_] -> StateT CabalInfo m [Relations]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Dependency_ -> CabalT m Relations
forall (m :: * -> *).
MonadIO m =>
Dependency_ -> CabalT m Relations
docDependencies [Dependency_]
libDeps
       Maybe BinPkgName
ghcdoc <- IO (Maybe BinPkgName) -> StateT CabalInfo m (Maybe BinPkgName)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe BinPkgName) -> StateT CabalInfo m (Maybe BinPkgName))
-> IO (Maybe BinPkgName) -> StateT CabalInfo m (Maybe BinPkgName)
forall a b. (a -> b) -> a -> b
$ CompilerFlavor -> PackageType -> IO (Maybe BinPkgName)
compilerPackageName CompilerFlavor
hc PackageType
B.Documentation
       let hcdocdep :: Relations
hcdocdep = if Bool
doc Bool -> Bool -> Bool
&& CompilerFlavor -> Set CompilerFlavor -> Bool
forall a. Ord a => a -> Set a -> Bool
member CompilerFlavor
GHC Set CompilerFlavor
hcs then Relations
-> (BinPkgName -> Relations) -> Maybe BinPkgName -> Relations
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (([Relation] -> Relations -> Relations
forall a. a -> [a] -> [a]
: []) ([Relation] -> Relations)
-> (BinPkgName -> [Relation]) -> BinPkgName -> Relations
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BinPkgName -> [Relation]
anyrel') Maybe BinPkgName
ghcdoc else []
       let xs :: Relations
xs = Relations -> Relations
forall a. Eq a => [a] -> [a]
nub (Relations -> Relations) -> Relations -> Relations
forall a b. (a -> b) -> a -> b
$ if Bool
doc Bool -> Bool -> Bool
&& Maybe Library -> Bool
forall a. Maybe a -> Bool
isJust (PackageDescription -> Maybe Library
Cabal.library PackageDescription
pkgDesc)
                      then Relations
hcdocdep Relations -> Relations -> Relations
forall a. [a] -> [a] -> [a]
++ Relations
bDeps Relations -> Relations -> Relations
forall a. [a] -> [a] -> [a]
++ [Relations] -> Relations
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [Relations]
cDeps
                      else []
       Relations -> CabalT m Relations
forall (m :: * -> *). Monad m => Relations -> CabalT m Relations
filterMissing Relations
xs

-- | The documentation dependencies for a package include the
-- documentation package for any libraries which are build
-- dependencies, so we have use to all the cross references.
docDependencies :: (MonadIO m) => Dependency_ -> CabalT m D.Relations
docDependencies :: Dependency_ -> CabalT m Relations
docDependencies (BuildDepends (Dependency PackageName
name VersionRange
ranges Set LibraryName
_)) =
    do CompilerFlavor
hc <- Getting CompilerFlavor CabalInfo CompilerFlavor
-> StateT CabalInfo m CompilerFlavor
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((DebInfo -> Const CompilerFlavor DebInfo)
-> CabalInfo -> Const CompilerFlavor CabalInfo
Lens' CabalInfo DebInfo
A.debInfo ((DebInfo -> Const CompilerFlavor DebInfo)
 -> CabalInfo -> Const CompilerFlavor CabalInfo)
-> ((CompilerFlavor -> Const CompilerFlavor CompilerFlavor)
    -> DebInfo -> Const CompilerFlavor DebInfo)
-> Getting CompilerFlavor CabalInfo CompilerFlavor
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Flags -> Const CompilerFlavor Flags)
-> DebInfo -> Const CompilerFlavor DebInfo
Lens' DebInfo Flags
D.flags ((Flags -> Const CompilerFlavor Flags)
 -> DebInfo -> Const CompilerFlavor DebInfo)
-> ((CompilerFlavor -> Const CompilerFlavor CompilerFlavor)
    -> Flags -> Const CompilerFlavor Flags)
-> (CompilerFlavor -> Const CompilerFlavor CompilerFlavor)
-> DebInfo
-> Const CompilerFlavor DebInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CompilerFlavor -> Const CompilerFlavor CompilerFlavor)
-> Flags -> Const CompilerFlavor Flags
Lens' Flags CompilerFlavor
compilerFlavor)
       let hcs :: Set CompilerFlavor
hcs = CompilerFlavor -> Set CompilerFlavor
forall a. a -> Set a
singleton CompilerFlavor
hc -- vestigial
       Bool
omitProfDeps <- Getting Bool CabalInfo Bool -> StateT CabalInfo m Bool
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((DebInfo -> Const Bool DebInfo)
-> CabalInfo -> Const Bool CabalInfo
Lens' CabalInfo DebInfo
A.debInfo ((DebInfo -> Const Bool DebInfo)
 -> CabalInfo -> Const Bool CabalInfo)
-> ((Bool -> Const Bool Bool) -> DebInfo -> Const Bool DebInfo)
-> Getting Bool CabalInfo Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Const Bool Bool) -> DebInfo -> Const Bool DebInfo
Lens' DebInfo Bool
D.omitProfVersionDeps)
       [Relations] -> Relations
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([Relations] -> Relations)
-> StateT CabalInfo m [Relations] -> CabalT m Relations
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (CompilerFlavor -> CabalT m Relations)
-> [CompilerFlavor] -> StateT CabalInfo m [Relations]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\ CompilerFlavor
hc' -> CompilerFlavor
-> PackageType
-> PackageName
-> VersionRange
-> Bool
-> CabalT m Relations
forall (m :: * -> *).
MonadIO m =>
CompilerFlavor
-> PackageType
-> PackageName
-> VersionRange
-> Bool
-> CabalT m Relations
dependencies CompilerFlavor
hc' PackageType
B.Documentation PackageName
name VersionRange
ranges Bool
omitProfDeps) (Set CompilerFlavor -> [CompilerFlavor]
forall a. Set a -> [a]
toList Set CompilerFlavor
hcs)
docDependencies Dependency_
_ = Relations -> CabalT m Relations
forall (m :: * -> *) a. Monad m => a -> m a
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 :: (MonadIO m) => Set (CompilerFlavor, B.PackageType) -> Dependency_ -> CabalT m D.Relations
buildDependencies :: Set (CompilerFlavor, PackageType)
-> Dependency_ -> CabalT m Relations
buildDependencies Set (CompilerFlavor, PackageType)
hcTypePairs (BuildDepends (Dependency PackageName
name VersionRange
ranges Set LibraryName
_)) =
    Getting Bool CabalInfo Bool -> StateT CabalInfo m Bool
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((DebInfo -> Const Bool DebInfo)
-> CabalInfo -> Const Bool CabalInfo
Lens' CabalInfo DebInfo
A.debInfo ((DebInfo -> Const Bool DebInfo)
 -> CabalInfo -> Const Bool CabalInfo)
-> ((Bool -> Const Bool Bool) -> DebInfo -> Const Bool DebInfo)
-> Getting Bool CabalInfo Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Const Bool Bool) -> DebInfo -> Const Bool DebInfo
Lens' DebInfo Bool
D.omitProfVersionDeps) StateT CabalInfo m Bool
-> (Bool -> CabalT m Relations) -> CabalT m Relations
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ Bool
omitProfDeps ->
    [Relations] -> Relations
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([Relations] -> Relations)
-> StateT CabalInfo m [Relations] -> CabalT m Relations
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((CompilerFlavor, PackageType) -> CabalT m Relations)
-> [(CompilerFlavor, PackageType)]
-> StateT CabalInfo m [Relations]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\ (CompilerFlavor
hc, PackageType
typ) -> CompilerFlavor
-> PackageType
-> PackageName
-> VersionRange
-> Bool
-> CabalT m Relations
forall (m :: * -> *).
MonadIO m =>
CompilerFlavor
-> PackageType
-> PackageName
-> VersionRange
-> Bool
-> CabalT m Relations
dependencies CompilerFlavor
hc PackageType
typ PackageName
name VersionRange
ranges Bool
omitProfDeps) (Set (CompilerFlavor, PackageType)
-> [(CompilerFlavor, PackageType)]
forall a. Set a -> [a]
toList Set (CompilerFlavor, PackageType)
hcTypePairs)
buildDependencies Set (CompilerFlavor, PackageType)
_ dep :: Dependency_
dep@(ExtraLibs Relations
_) =
    do Map String Relations
mp <- Getting (Map String Relations) CabalInfo (Map String Relations)
-> StateT CabalInfo m (Map String Relations)
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((DebInfo -> Const (Map String Relations) DebInfo)
-> CabalInfo -> Const (Map String Relations) CabalInfo
Lens' CabalInfo DebInfo
A.debInfo ((DebInfo -> Const (Map String Relations) DebInfo)
 -> CabalInfo -> Const (Map String Relations) CabalInfo)
-> ((Map String Relations
     -> Const (Map String Relations) (Map String Relations))
    -> DebInfo -> Const (Map String Relations) DebInfo)
-> Getting (Map String Relations) CabalInfo (Map String Relations)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Map String Relations
 -> Const (Map String Relations) (Map String Relations))
-> DebInfo -> Const (Map String Relations) DebInfo
Lens' DebInfo (Map String Relations)
D.execMap)
       Relations -> CabalT m Relations
forall (m :: * -> *) a. Monad m => a -> m a
return (Relations -> CabalT m Relations)
-> Relations -> CabalT m Relations
forall a b. (a -> b) -> a -> b
$ [Relations] -> Relations
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([Relations] -> Relations) -> [Relations] -> Relations
forall a b. (a -> b) -> a -> b
$ Map String Relations -> Dependency_ -> [Relations]
adapt Map String Relations
mp Dependency_
dep
buildDependencies Set (CompilerFlavor, PackageType)
_ Dependency_
dep =
    case Dependency_ -> Maybe Dependency
unboxDependency Dependency_
dep of
      Just (Dependency PackageName
_name VersionRange
_ranges Set LibraryName
_) ->
          do Map String Relations
mp <- Getting (Map String Relations) CabalInfo (Map String Relations)
-> CabalInfo -> Map String Relations
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view ((DebInfo -> Const (Map String Relations) DebInfo)
-> CabalInfo -> Const (Map String Relations) CabalInfo
Lens' CabalInfo DebInfo
A.debInfo ((DebInfo -> Const (Map String Relations) DebInfo)
 -> CabalInfo -> Const (Map String Relations) CabalInfo)
-> ((Map String Relations
     -> Const (Map String Relations) (Map String Relations))
    -> DebInfo -> Const (Map String Relations) DebInfo)
-> Getting (Map String Relations) CabalInfo (Map String Relations)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Map String Relations
 -> Const (Map String Relations) (Map String Relations))
-> DebInfo -> Const (Map String Relations) DebInfo
Lens' DebInfo (Map String Relations)
D.execMap) (CabalInfo -> Map String Relations)
-> StateT CabalInfo m CabalInfo
-> StateT CabalInfo m (Map String Relations)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT CabalInfo m CabalInfo
forall s (m :: * -> *). MonadState s m => m s
get
             Relations -> CabalT m Relations
forall (m :: * -> *) a. Monad m => a -> m a
return (Relations -> CabalT m Relations)
-> Relations -> CabalT m Relations
forall a b. (a -> b) -> a -> b
$ [Relations] -> Relations
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([Relations] -> Relations) -> [Relations] -> Relations
forall a b. (a -> b) -> a -> b
$ Map String Relations -> Dependency_ -> [Relations]
adapt Map String Relations
mp Dependency_
dep
      Maybe Dependency
Nothing ->
          Relations -> CabalT m Relations
forall (m :: * -> *) a. Monad m => a -> m a
return []

adapt :: Map.Map String Relations -> Dependency_ -> [Relations]
adapt :: Map String Relations -> Dependency_ -> [Relations]
adapt Map String Relations
mp (PkgConfigDepends (Dependency PackageName
pkg VersionRange
_ Set LibraryName
_)) =
    [Relations]
-> (Relations -> [Relations]) -> Maybe Relations -> [Relations]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> [Relations]
aptFile (PackageName -> String
unPackageName PackageName
pkg)) (Relations -> [Relations] -> [Relations]
forall a. a -> [a] -> [a]
: []) (String -> Map String Relations -> Maybe Relations
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (PackageName -> String
unPackageName PackageName
pkg) Map String Relations
mp)
adapt Map String Relations
mp (BuildTools (Dependency PackageName
pkg VersionRange
_ Set LibraryName
_)) =
    [Relations]
-> (Relations -> [Relations]) -> Maybe Relations -> [Relations]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> [Relations]
aptFile (PackageName -> String
unPackageName PackageName
pkg)) (Relations -> [Relations] -> [Relations]
forall a. a -> [a] -> [a]
: []) (String -> Map String Relations -> Maybe Relations
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (PackageName -> String
unPackageName PackageName
pkg) Map String Relations
mp)
adapt Map String Relations
_flags (ExtraLibs Relations
x) = [Relations
x]
adapt Map String Relations
_flags (BuildDepends (Dependency PackageName
pkg VersionRange
_ Set LibraryName
_)) = [[[BinPkgName -> Maybe VersionReq -> Maybe ArchitectureReq -> Relation
D.Rel (String -> BinPkgName
D.BinPkgName (PackageName -> String
unPackageName PackageName
pkg)) Maybe VersionReq
forall a. Maybe a
Nothing Maybe ArchitectureReq
forall a. Maybe a
Nothing]]]

-- There are three 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, (2) the package
-- we are looking for may not be installed in the parent
-- environment, and (3) the apt-file executable is not installed.
aptFile :: String -> [Relations] -- Maybe would probably be more correct
aptFile :: String -> [Relations]
aptFile String
pkg = IO [Relations] -> [Relations]
forall a. IO a -> a
unsafePerformIO (IO [Relations] -> [Relations]) -> IO [Relations] -> [Relations]
forall a b. (a -> b) -> a -> b
$
    String -> IO (Maybe String)
findExecutable String
"apt-file" IO (Maybe String)
-> (Maybe String -> IO [Relations]) -> IO [Relations]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe String -> IO [Relations]
aptFile'
  where
    aptFile' :: Maybe String -> IO [Relations]
aptFile' Maybe String
Nothing = String -> IO [Relations]
forall a. HasCallStack => String -> a
error String
"The apt-file executable could not be found."
    aptFile' (Just String
aptfile) = do
        (ExitCode, String, String)
ret <- String -> [String] -> String -> IO (ExitCode, String, String)
readProcessWithExitCode String
aptfile [String
"-l", String
"search", String
pkg String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
".pc"] String
""
        [Relations] -> IO [Relations]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Relations] -> IO [Relations]) -> [Relations] -> IO [Relations]
forall a b. (a -> b) -> a -> b
$ case (ExitCode, String, String)
ret of
                  (ExitCode
ExitSuccess, String
out, String
_) ->
                      case (Char -> Bool) -> ShowS
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isSpace) String
out of
                        String
"" -> String -> [Relations]
forall a. HasCallStack => String -> a
error (String -> [Relations]) -> String -> [Relations]
forall a b. (a -> b) -> a -> b
$ String
"Unable to locate a debian package containing the build tool " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
pkg String -> ShowS
forall a. [a] -> [a] -> [a]
++
                                      String
", try using --exec-map " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
pkg String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
":<debname> or execMap " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> String
show String
pkg String -> ShowS
forall a. [a] -> [a] -> [a]
++
                                      String
" [[Rel (BinPkgName \"<debname>\") Nothing Nothing]]"
                        String
s -> [[[BinPkgName -> Maybe VersionReq -> Maybe ArchitectureReq -> Relation
D.Rel (String -> BinPkgName
D.BinPkgName String
s) Maybe VersionReq
forall a. Maybe a
Nothing Maybe ArchitectureReq
forall a. Maybe a
Nothing]]]
                  (ExitCode, String, String)
_ -> []

anyrel :: String -> [D.Relation]
anyrel :: String -> [Relation]
anyrel String
x = BinPkgName -> [Relation]
anyrel' (String -> BinPkgName
D.BinPkgName String
x)

anyrel' :: D.BinPkgName -> [D.Relation]
anyrel' :: BinPkgName -> [Relation]
anyrel' BinPkgName
x = [BinPkgName -> Maybe VersionReq -> Maybe ArchitectureReq -> Relation
D.Rel BinPkgName
x Maybe VersionReq
forall a. Maybe a
Nothing Maybe ArchitectureReq
forall a. Maybe a
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 :: MonadIO m => CompilerFlavor -> B.PackageType -> PackageName -> VersionRange -> Bool -> CabalT m Relations
dependencies :: CompilerFlavor
-> PackageType
-> PackageName
-> VersionRange
-> Bool
-> CabalT m Relations
dependencies CompilerFlavor
hc PackageType
typ PackageName
name VersionRange
cabalRange Bool
omitProfVersionDeps =
    do Map PackageName VersionSplits
nameMap <- Getting
  (Map PackageName VersionSplits)
  CabalInfo
  (Map PackageName VersionSplits)
-> StateT CabalInfo m (Map PackageName VersionSplits)
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use Getting
  (Map PackageName VersionSplits)
  CabalInfo
  (Map PackageName VersionSplits)
Lens' CabalInfo (Map PackageName VersionSplits)
A.debianNameMap
       -- 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 :: [(BinPkgName, VersionRange)]
           alts :: [(BinPkgName, VersionRange)]
alts = case PackageName -> Map PackageName VersionSplits -> Maybe VersionSplits
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup PackageName
name Map PackageName VersionSplits
nameMap of
                    -- If there are no splits for this package just
                    -- return the single dependency for the package.
                    Maybe VersionSplits
Nothing -> [(CompilerFlavor -> PackageName -> PackageType -> BinPkgName
forall name.
PkgName name =>
CompilerFlavor -> PackageName -> PackageType -> name
mkPkgName CompilerFlavor
hc PackageName
name PackageType
typ, VersionRange
cabalRange')]
                    -- If there are splits create a list of (debian package name, VersionRange) pairs
                    Just VersionSplits
splits' -> ((DebBase, VersionRange) -> (BinPkgName, VersionRange))
-> [(DebBase, VersionRange)] -> [(BinPkgName, VersionRange)]
forall a b. (a -> b) -> [a] -> [b]
List.map (\ (DebBase
n, VersionRange
r) -> (CompilerFlavor -> PackageType -> DebBase -> BinPkgName
forall name.
PkgName name =>
CompilerFlavor -> PackageType -> DebBase -> name
mkPkgName' CompilerFlavor
hc PackageType
typ DebBase
n, VersionRange
r)) (VersionSplits -> [(DebBase, VersionRange)]
packageRangesFromVersionSplits VersionSplits
splits')
       ((BinPkgName, VersionRange)
 -> StateT CabalInfo m (Maybe (Rels Relation)))
-> [(BinPkgName, VersionRange)]
-> StateT CabalInfo m [Maybe (Rels Relation)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (BinPkgName, VersionRange)
-> StateT CabalInfo m (Maybe (Rels Relation))
forall (m :: * -> *).
Monad m =>
(BinPkgName, VersionRange)
-> StateT CabalInfo m (Maybe (Rels Relation))
convert [(BinPkgName, VersionRange)]
alts StateT CabalInfo m [Maybe (Rels Relation)]
-> ([Maybe (Rels Relation)] -> CabalT m Relations)
-> CabalT m Relations
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ([Relation] -> StateT CabalInfo m [Relation])
-> Relations -> CabalT m Relations
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (PackageType
-> PackageName
-> CompilerFlavor
-> [Relation]
-> StateT CabalInfo m [Relation]
forall (m :: * -> *).
MonadIO m =>
PackageType
-> PackageName
-> CompilerFlavor
-> [Relation]
-> CabalT m [Relation]
doBundled PackageType
typ PackageName
name CompilerFlavor
hc) (Relations -> CabalT m Relations)
-> ([Maybe (Rels Relation)] -> Relations)
-> [Maybe (Rels Relation)]
-> CabalT m Relations
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rels Relation -> Relations
forall a. Rels a -> [[a]]
convert' (Rels Relation -> Relations)
-> ([Maybe (Rels Relation)] -> Rels Relation)
-> [Maybe (Rels Relation)]
-> Relations
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rels Relation -> Rels Relation
forall a. Rels a -> Rels a
canonical (Rels Relation -> Rels Relation)
-> ([Maybe (Rels Relation)] -> Rels Relation)
-> [Maybe (Rels Relation)]
-> Rels Relation
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Rels Relation] -> Rels Relation
forall a. [Rels a] -> Rels a
Or ([Rels Relation] -> Rels Relation)
-> ([Maybe (Rels Relation)] -> [Rels Relation])
-> [Maybe (Rels Relation)]
-> Rels Relation
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe (Rels Relation)] -> [Rels Relation]
forall a. [Maybe a] -> [a]
catMaybes
    where
      convert :: (BinPkgName, VersionRange)
-> StateT CabalInfo m (Maybe (Rels Relation))
convert (BinPkgName
dname, VersionRange
range) =
          case VersionRange -> Bool
isNoVersion VersionRange
range''' of
            Bool
True -> Maybe (Rels Relation) -> StateT CabalInfo m (Maybe (Rels Relation))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Rels Relation)
forall a. Maybe a
Nothing
            Bool
False ->
                Rels Relation -> Maybe (Rels Relation)
forall a. a -> Maybe a
Just (Rels Relation -> Maybe (Rels Relation))
-> StateT CabalInfo m (Rels Relation)
-> StateT CabalInfo m (Maybe (Rels Relation))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((VersionRangeF (StateT CabalInfo m (Rels Relation))
 -> StateT CabalInfo m (Rels Relation))
-> VersionRange -> StateT CabalInfo m (Rels Relation)
forall a. (VersionRangeF a -> a) -> VersionRange -> a
cataVersionRange VersionRangeF (StateT CabalInfo m (Rels Relation))
-> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *).
Monad m =>
VersionRangeF (StateT CabalInfo m (Rels Relation))
-> StateT CabalInfo m (Rels Relation)
rangeToRange (VersionRange -> StateT CabalInfo m (Rels Relation))
-> (VersionRange -> VersionRange)
-> VersionRange
-> StateT CabalInfo m (Rels Relation)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VersionRange -> VersionRange
normaliseVersionRange) VersionRange
range'''
          where
#if !MIN_VERSION_Cabal(3,4,0)
            rangeToRange :: VersionRangeF (StateT CabalInfo m (Rels Relation))
-> StateT CabalInfo m (Rels Relation)
rangeToRange VersionRangeF (StateT CabalInfo m (Rels Relation))
AnyVersionF                     = Rels Relation -> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a. Monad m => a -> m a
return (Rels Relation -> StateT CabalInfo m (Rels Relation))
-> Rels Relation -> StateT CabalInfo m (Rels Relation)
forall a b. (a -> b) -> a -> b
$ Relation -> Rels Relation
forall a. a -> Rels a
Rel' (BinPkgName -> Maybe VersionReq -> Maybe ArchitectureReq -> Relation
D.Rel BinPkgName
dname Maybe VersionReq
forall a. Maybe a
Nothing Maybe ArchitectureReq
forall a. Maybe a
Nothing)
#endif
            rangeToRange (ThisVersionF Version
v)                = (PackageName -> Version -> CabalT m DebianVersion
forall (m :: * -> *).
Monad m =>
PackageName -> Version -> CabalT m DebianVersion
debianVersion' PackageName
name (Version -> CabalT m DebianVersion)
-> (DebianVersion -> StateT CabalInfo m (Rels Relation))
-> Version
-> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> \ DebianVersion
dv -> Rels Relation -> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a. Monad m => a -> m a
return (Rels Relation -> StateT CabalInfo m (Rels Relation))
-> Rels Relation -> StateT CabalInfo m (Rels Relation)
forall a b. (a -> b) -> a -> b
$ Relation -> Rels Relation
forall a. a -> Rels a
Rel' (BinPkgName -> Maybe VersionReq -> Maybe ArchitectureReq -> Relation
D.Rel BinPkgName
dname (VersionReq -> Maybe VersionReq
forall a. a -> Maybe a
Just (DebianVersion -> VersionReq
D.EEQ DebianVersion
dv)) Maybe ArchitectureReq
forall a. Maybe a
Nothing)) Version
v
            rangeToRange (LaterVersionF Version
v)               = (PackageName -> Version -> CabalT m DebianVersion
forall (m :: * -> *).
Monad m =>
PackageName -> Version -> CabalT m DebianVersion
debianVersion' PackageName
name (Version -> CabalT m DebianVersion)
-> (DebianVersion -> StateT CabalInfo m (Rels Relation))
-> Version
-> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> \ DebianVersion
dv -> Rels Relation -> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a. Monad m => a -> m a
return (Rels Relation -> StateT CabalInfo m (Rels Relation))
-> Rels Relation -> StateT CabalInfo m (Rels Relation)
forall a b. (a -> b) -> a -> b
$ Relation -> Rels Relation
forall a. a -> Rels a
Rel' (BinPkgName -> Maybe VersionReq -> Maybe ArchitectureReq -> Relation
D.Rel BinPkgName
dname (VersionReq -> Maybe VersionReq
forall a. a -> Maybe a
Just (DebianVersion -> VersionReq
D.SGR DebianVersion
dv)) Maybe ArchitectureReq
forall a. Maybe a
Nothing)) Version
v
            rangeToRange (EarlierVersionF Version
v)             = (PackageName -> Version -> CabalT m DebianVersion
forall (m :: * -> *).
Monad m =>
PackageName -> Version -> CabalT m DebianVersion
debianVersion' PackageName
name (Version -> CabalT m DebianVersion)
-> (DebianVersion -> StateT CabalInfo m (Rels Relation))
-> Version
-> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> \ DebianVersion
dv -> Rels Relation -> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a. Monad m => a -> m a
return (Rels Relation -> StateT CabalInfo m (Rels Relation))
-> Rels Relation -> StateT CabalInfo m (Rels Relation)
forall a b. (a -> b) -> a -> b
$ Relation -> Rels Relation
forall a. a -> Rels a
Rel' (BinPkgName -> Maybe VersionReq -> Maybe ArchitectureReq -> Relation
D.Rel BinPkgName
dname (VersionReq -> Maybe VersionReq
forall a. a -> Maybe a
Just (DebianVersion -> VersionReq
D.SLT DebianVersion
dv)) Maybe ArchitectureReq
forall a. Maybe a
Nothing)) Version
v
            rangeToRange (OrLaterVersionF Version
v)
               | Version
v Version -> Version -> Bool
forall a. Eq a => a -> a -> Bool
== [Int] -> Version
mkVersion [Int
0] = Rels Relation -> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a. Monad m => a -> m a
return (Rels Relation -> StateT CabalInfo m (Rels Relation))
-> Rels Relation -> StateT CabalInfo m (Rels Relation)
forall a b. (a -> b) -> a -> b
$ Relation -> Rels Relation
forall a. a -> Rels a
Rel' (BinPkgName -> Maybe VersionReq -> Maybe ArchitectureReq -> Relation
D.Rel BinPkgName
dname Maybe VersionReq
forall a. Maybe a
Nothing Maybe ArchitectureReq
forall a. Maybe a
Nothing)
               | Bool
otherwise = (PackageName -> Version -> CabalT m DebianVersion
forall (m :: * -> *).
Monad m =>
PackageName -> Version -> CabalT m DebianVersion
debianVersion' PackageName
name (Version -> CabalT m DebianVersion)
-> (DebianVersion -> StateT CabalInfo m (Rels Relation))
-> Version
-> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> \ DebianVersion
dv -> Rels Relation -> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a. Monad m => a -> m a
return (Rels Relation -> StateT CabalInfo m (Rels Relation))
-> Rels Relation -> StateT CabalInfo m (Rels Relation)
forall a b. (a -> b) -> a -> b
$ Relation -> Rels Relation
forall a. a -> Rels a
Rel' (BinPkgName -> Maybe VersionReq -> Maybe ArchitectureReq -> Relation
D.Rel BinPkgName
dname (VersionReq -> Maybe VersionReq
forall a. a -> Maybe a
Just (DebianVersion -> VersionReq
D.GRE DebianVersion
dv)) Maybe ArchitectureReq
forall a. Maybe a
Nothing)) Version
v
            rangeToRange (OrEarlierVersionF Version
v)           = (PackageName -> Version -> CabalT m DebianVersion
forall (m :: * -> *).
Monad m =>
PackageName -> Version -> CabalT m DebianVersion
debianVersion' PackageName
name (Version -> CabalT m DebianVersion)
-> (DebianVersion -> StateT CabalInfo m (Rels Relation))
-> Version
-> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> \ DebianVersion
dv -> Rels Relation -> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a. Monad m => a -> m a
return (Rels Relation -> StateT CabalInfo m (Rels Relation))
-> Rels Relation -> StateT CabalInfo m (Rels Relation)
forall a b. (a -> b) -> a -> b
$ Relation -> Rels Relation
forall a. a -> Rels a
Rel' (BinPkgName -> Maybe VersionReq -> Maybe ArchitectureReq -> Relation
D.Rel BinPkgName
dname (VersionReq -> Maybe VersionReq
forall a. a -> Maybe a
Just (DebianVersion -> VersionReq
D.LTE DebianVersion
dv)) Maybe ArchitectureReq
forall a. Maybe a
Nothing)) Version
v
#if !MIN_VERSION_Cabal(3,4,0)
            rangeToRange (WildcardVersionF Version
v)            = (\ Version
x Version
y -> PackageName -> Version -> CabalT m DebianVersion
forall (m :: * -> *).
Monad m =>
PackageName -> Version -> CabalT m DebianVersion
debianVersion' PackageName
name Version
x CabalT m DebianVersion
-> (DebianVersion -> StateT CabalInfo m (Rels Relation))
-> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ DebianVersion
dvx ->
                                    PackageName -> Version -> CabalT m DebianVersion
forall (m :: * -> *).
Monad m =>
PackageName -> Version -> CabalT m DebianVersion
debianVersion' PackageName
name Version
y CabalT m DebianVersion
-> (DebianVersion -> StateT CabalInfo m (Rels Relation))
-> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ DebianVersion
dvy ->
                                    Rels Relation -> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a. Monad m => a -> m a
return (Rels Relation -> StateT CabalInfo m (Rels Relation))
-> Rels Relation -> StateT CabalInfo m (Rels Relation)
forall a b. (a -> b) -> a -> b
$ [Rels Relation] -> Rels Relation
forall a. [Rels a] -> Rels a
And [Relation -> Rels Relation
forall a. a -> Rels a
Rel' (BinPkgName -> Maybe VersionReq -> Maybe ArchitectureReq -> Relation
D.Rel BinPkgName
dname (VersionReq -> Maybe VersionReq
forall a. a -> Maybe a
Just (DebianVersion -> VersionReq
D.GRE DebianVersion
dvx)) Maybe ArchitectureReq
forall a. Maybe a
Nothing),
                                                  Relation -> Rels Relation
forall a. a -> Rels a
Rel' (BinPkgName -> Maybe VersionReq -> Maybe ArchitectureReq -> Relation
D.Rel BinPkgName
dname (VersionReq -> Maybe VersionReq
forall a. a -> Maybe a
Just (DebianVersion -> VersionReq
D.SLT DebianVersion
dvy)) Maybe ArchitectureReq
forall a. Maybe a
Nothing)]) Version
v (Version -> Version
wildcardUpperBound Version
v)
#endif
            rangeToRange (MajorBoundVersionF Version
v)          = (\ Version
x Version
y -> PackageName -> Version -> CabalT m DebianVersion
forall (m :: * -> *).
Monad m =>
PackageName -> Version -> CabalT m DebianVersion
debianVersion' PackageName
name Version
x CabalT m DebianVersion
-> (DebianVersion -> StateT CabalInfo m (Rels Relation))
-> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ DebianVersion
dvx ->
                                    PackageName -> Version -> CabalT m DebianVersion
forall (m :: * -> *).
Monad m =>
PackageName -> Version -> CabalT m DebianVersion
debianVersion' PackageName
name Version
y CabalT m DebianVersion
-> (DebianVersion -> StateT CabalInfo m (Rels Relation))
-> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ DebianVersion
dvy ->
                                    Rels Relation -> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a. Monad m => a -> m a
return (Rels Relation -> StateT CabalInfo m (Rels Relation))
-> Rels Relation -> StateT CabalInfo m (Rels Relation)
forall a b. (a -> b) -> a -> b
$ [Rels Relation] -> Rels Relation
forall a. [Rels a] -> Rels a
And [Relation -> Rels Relation
forall a. a -> Rels a
Rel' (BinPkgName -> Maybe VersionReq -> Maybe ArchitectureReq -> Relation
D.Rel BinPkgName
dname (VersionReq -> Maybe VersionReq
forall a. a -> Maybe a
Just (DebianVersion -> VersionReq
D.GRE DebianVersion
dvx)) Maybe ArchitectureReq
forall a. Maybe a
Nothing),
                                                  Relation -> Rels Relation
forall a. a -> Rels a
Rel' (BinPkgName -> Maybe VersionReq -> Maybe ArchitectureReq -> Relation
D.Rel BinPkgName
dname (VersionReq -> Maybe VersionReq
forall a. a -> Maybe a
Just (DebianVersion -> VersionReq
D.SLT DebianVersion
dvy)) Maybe ArchitectureReq
forall a. Maybe a
Nothing)]) Version
v (Version -> Version
majorUpperBound Version
v)
            rangeToRange (UnionVersionRangesF StateT CabalInfo m (Rels Relation)
v1 StateT CabalInfo m (Rels Relation)
v2)     = (\ StateT CabalInfo m (Rels Relation)
x StateT CabalInfo m (Rels Relation)
y -> StateT CabalInfo m (Rels Relation)
x StateT CabalInfo m (Rels Relation)
-> (Rels Relation -> StateT CabalInfo m (Rels Relation))
-> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ Rels Relation
x' -> StateT CabalInfo m (Rels Relation)
y StateT CabalInfo m (Rels Relation)
-> (Rels Relation -> StateT CabalInfo m (Rels Relation))
-> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ Rels Relation
y' -> Rels Relation -> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a. Monad m => a -> m a
return (Rels Relation -> StateT CabalInfo m (Rels Relation))
-> Rels Relation -> StateT CabalInfo m (Rels Relation)
forall a b. (a -> b) -> a -> b
$ [Rels Relation] -> Rels Relation
forall a. [Rels a] -> Rels a
Or [Rels Relation
x', Rels Relation
y']) StateT CabalInfo m (Rels Relation)
v1 StateT CabalInfo m (Rels Relation)
v2
            rangeToRange (IntersectVersionRangesF StateT CabalInfo m (Rels Relation)
v1 StateT CabalInfo m (Rels Relation)
v2) = (\ StateT CabalInfo m (Rels Relation)
x StateT CabalInfo m (Rels Relation)
y -> StateT CabalInfo m (Rels Relation)
x StateT CabalInfo m (Rels Relation)
-> (Rels Relation -> StateT CabalInfo m (Rels Relation))
-> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ Rels Relation
x' -> StateT CabalInfo m (Rels Relation)
y StateT CabalInfo m (Rels Relation)
-> (Rels Relation -> StateT CabalInfo m (Rels Relation))
-> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ Rels Relation
y' -> Rels Relation -> StateT CabalInfo m (Rels Relation)
forall (m :: * -> *) a. Monad m => a -> m a
return (Rels Relation -> StateT CabalInfo m (Rels Relation))
-> Rels Relation -> StateT CabalInfo m (Rels Relation)
forall a b. (a -> b) -> a -> b
$ [Rels Relation] -> Rels Relation
forall a. [Rels a] -> Rels a
And [Rels Relation
x', Rels Relation
y']) StateT CabalInfo m (Rels Relation)
v1 StateT CabalInfo m (Rels Relation)
v2
#if !MIN_VERSION_Cabal(3,4,0)
            rangeToRange (VersionRangeParensF StateT CabalInfo m (Rels Relation)
v)         = StateT CabalInfo m (Rels Relation)
v
#endif
            -- Choose the simpler of the two
            range''' :: VersionRange
range''' = VersionRange -> VersionRange
canon (VersionRange -> VersionRange -> VersionRange
simpler VersionRange
range' VersionRange
range'')
            -- Unrestrict the range for versions that we know don't exist for this debian package
#if MIN_VERSION_Cabal(3,6,0)
            range'' = range' -- inversion functions are gone
#else
            range'' :: VersionRange
range'' = VersionRange -> VersionRange
canon (VersionRange -> VersionRange -> VersionRange
unionVersionRanges VersionRange
range' (VersionRange -> VersionRange
invertVersionRange VersionRange
range))
#endif
            -- Restrict the range to the versions specified for this debian package
            range' :: VersionRange
range' = VersionRange -> VersionRange -> VersionRange
intersectVersionRanges VersionRange
cabalRange' VersionRange
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' :: VersionRange
cabalRange' | PackageType
typ PackageType -> [PackageType] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [PackageType]
noVersionPackageType = VersionRange
anyVersion
                  | Bool
otherwise = ((VersionRangeF VersionRange -> VersionRange)
-> (VersionRange -> VersionRangeF VersionRange)
-> VersionRange
-> VersionRange
hyloVersionRange VersionRangeF VersionRange -> VersionRange
tweak VersionRange -> VersionRangeF VersionRange
projectVersionRange (VersionRange -> VersionRange)
-> (VersionRange -> VersionRange) -> VersionRange -> VersionRange
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VersionRange -> VersionRange
normaliseVersionRange) VersionRange
cabalRange
      tweak :: VersionRangeF VersionRange -> VersionRange
tweak (ThisVersionF Version
v) = Version -> VersionRange
withinVersion Version
v
      tweak VersionRangeF VersionRange
vr = VersionRangeF VersionRange -> VersionRange
embedVersionRange VersionRangeF VersionRange
vr
      noVersionPackageType :: [PackageType]
noVersionPackageType = (if Bool
omitProfVersionDeps then [PackageType
B.Profiling] else []) [PackageType] -> [PackageType] -> [PackageType]
forall a. [a] -> [a] -> [a]
++ [PackageType
B.Documentation]
      simpler :: VersionRange -> VersionRange -> VersionRange
simpler VersionRange
v1 VersionRange
v2 = (VersionRange -> VersionRange -> Ordering)
-> [VersionRange] -> VersionRange
forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
minimumBy (Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Int -> Int -> Ordering)
-> (VersionRange -> Int)
-> VersionRange
-> VersionRange
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` ([VersionInterval] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([VersionInterval] -> Int)
-> (VersionRange -> [VersionInterval]) -> VersionRange -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VersionRange -> [VersionInterval]
asVersionIntervals)) [VersionRange
v1, VersionRange
v2]
      -- Simplify a VersionRange
      canon :: VersionRange -> VersionRange
canon = VersionIntervals -> VersionRange
fromVersionIntervals (VersionIntervals -> VersionRange)
-> (VersionRange -> VersionIntervals)
-> VersionRange
-> VersionRange
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VersionRange -> VersionIntervals
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 :: MonadIO m =>
             B.PackageType
          -> PackageName
          -> CompilerFlavor
          -> [D.Relation]
          -> CabalT m [D.Relation]
doBundled :: PackageType
-> PackageName
-> CompilerFlavor
-> [Relation]
-> CabalT m [Relation]
doBundled PackageType
typ PackageName
name CompilerFlavor
hc [Relation]
rels = do
  Maybe BinPkgName
hcname <- IO (Maybe BinPkgName) -> StateT CabalInfo m (Maybe BinPkgName)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe BinPkgName) -> StateT CabalInfo m (Maybe BinPkgName))
-> IO (Maybe BinPkgName) -> StateT CabalInfo m (Maybe BinPkgName)
forall a b. (a -> b) -> a -> b
$ CompilerFlavor -> PackageType -> IO (Maybe BinPkgName)
compilerPackageName CompilerFlavor
hc PackageType
typ
  Relations -> [Relation]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (Relations -> [Relation])
-> StateT CabalInfo m Relations -> CabalT m [Relation]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Relation -> CabalT m [Relation])
-> [Relation] -> StateT CabalInfo m Relations
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Maybe BinPkgName -> Relation -> CabalT m [Relation]
forall (m :: * -> *).
MonadIO m =>
Maybe BinPkgName -> Relation -> CabalT m [Relation]
doRel Maybe BinPkgName
hcname) [Relation]
rels
    where
      -- If a library is built into the compiler, this is the debian
      -- package name the compiler will conflict with.
      doRel :: MonadIO m => Maybe BinPkgName -> D.Relation -> CabalT m [D.Relation]
      doRel :: Maybe BinPkgName -> Relation -> CabalT m [Relation]
doRel Maybe BinPkgName
hcname rel :: Relation
rel@(D.Rel BinPkgName
dname Maybe VersionReq
req Maybe ArchitectureReq
_) = do
        let comp :: [Relation]
comp = [Relation]
-> (BinPkgName -> [Relation]) -> Maybe BinPkgName -> [Relation]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\BinPkgName
x -> [BinPkgName -> Maybe VersionReq -> Maybe ArchitectureReq -> Relation
D.Rel BinPkgName
x Maybe VersionReq
forall a. Maybe a
Nothing Maybe ArchitectureReq
forall a. Maybe a
Nothing]) Maybe BinPkgName
hcname
        -- gver <- use ghcVersion
        -- Look at what version of the package is provided by the compiler.
        CabalInfo
atoms <- StateT CabalInfo m CabalInfo
forall s (m :: * -> *). MonadState s m => m s
get
        -- What version of this package (if any) does the compiler provide?
        [PackageIdentifier]
relInfo <- IO [PackageIdentifier] -> StateT CabalInfo m [PackageIdentifier]
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [PackageIdentifier] -> StateT CabalInfo m [PackageIdentifier])
-> IO [PackageIdentifier] -> StateT CabalInfo m [PackageIdentifier]
forall a b. (a -> b) -> a -> b
$ CompilerFlavor -> IO [PackageIdentifier]
builtIn CompilerFlavor
hc
        let pver :: Maybe DebianVersion
pver = [DebianVersion] -> Maybe DebianVersion
forall a. [a] -> Maybe a
listToMaybe ([DebianVersion] -> Maybe DebianVersion)
-> [DebianVersion] -> Maybe DebianVersion
forall a b. (a -> b) -> a -> b
$ (PackageIdentifier -> DebianVersion)
-> [PackageIdentifier] -> [DebianVersion]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (CabalInfo -> PackageIdentifier -> DebianVersion
debianVersion'' CabalInfo
atoms) ((PackageIdentifier -> Bool)
-> [PackageIdentifier] -> [PackageIdentifier]
forall a. (a -> Bool) -> [a] -> [a]
filter ((PackageName -> PackageName -> Bool
forall a. Eq a => a -> a -> Bool
== PackageName
name) (PackageName -> Bool)
-> (PackageIdentifier -> PackageName) -> PackageIdentifier -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageIdentifier -> PackageName
pkgName) [PackageIdentifier]
relInfo)
        -- The name this library would have if it was in the compiler conflicts list.
        let naiveDebianName :: BinPkgName
naiveDebianName = CompilerFlavor -> PackageName -> PackageType -> BinPkgName
forall name.
PkgName name =>
CompilerFlavor -> PackageName -> PackageType -> name
mkPkgName CompilerFlavor
hc PackageName
name PackageType
typ
        -- The compiler should appear in the build dependency
        -- if it provides a suitable version of the library,
        -- or if it conflicts with all versions of the
        -- library (which, if pver is Nothing, will certainly
        -- result in an error which needs to be corrected in
        -- the packaging.)
        let compilerDependency :: [Relation]
compilerDependency = if Maybe DebianVersion -> Bool
forall a. Maybe a -> Bool
isJust Maybe DebianVersion
pver Bool -> Bool -> Bool
&& (Maybe VersionReq -> Maybe DebianVersion -> Bool
checkVersionReq Maybe VersionReq
req Maybe DebianVersion
pver Bool -> Bool -> Bool
|| BinPkgName
dname BinPkgName -> BinPkgName -> Bool
forall a. Eq a => a -> a -> Bool
== BinPkgName
naiveDebianName) then [Relation]
comp else []
        -- The library package can satisfy the dependency if
        -- the compiler doesn't provide a version, or if the
        -- compiler doesn't conflict with the package's
        -- debian name.
        let libraryDependency :: [Relation]
libraryDependency = if Maybe DebianVersion -> Bool
forall a. Maybe a -> Bool
isNothing Maybe DebianVersion
pver Bool -> Bool -> Bool
|| BinPkgName
dname BinPkgName -> BinPkgName -> Bool
forall a. Eq a => a -> a -> Bool
/= BinPkgName
naiveDebianName then [Relation
rel] else []
        -- Is the version number in the library dependency newer than
        -- the compiler version?  If so it should appear to its left,
        -- otherwise to its right.
        [Relation] -> CabalT m [Relation]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Relation] -> CabalT m [Relation])
-> [Relation] -> CabalT m [Relation]
forall a b. (a -> b) -> a -> b
$ case Maybe VersionReq
req of
                   Just (D.SLT DebianVersion
lver) | DebianVersion -> Maybe DebianVersion
forall a. a -> Maybe a
Just DebianVersion
lver Maybe DebianVersion -> Maybe DebianVersion -> Bool
forall a. Ord a => a -> a -> Bool
< Maybe DebianVersion
pver -> [Relation]
compilerDependency [Relation] -> [Relation] -> [Relation]
forall a. [a] -> [a] -> [a]
++ [Relation]
libraryDependency
                   Just (D.LTE DebianVersion
lver) | DebianVersion -> Maybe DebianVersion
forall a. a -> Maybe a
Just DebianVersion
lver Maybe DebianVersion -> Maybe DebianVersion -> Bool
forall a. Ord a => a -> a -> Bool
< Maybe DebianVersion
pver -> [Relation]
compilerDependency [Relation] -> [Relation] -> [Relation]
forall a. [a] -> [a] -> [a]
++ [Relation]
libraryDependency
                   Just (D.EEQ DebianVersion
lver) | DebianVersion -> Maybe DebianVersion
forall a. a -> Maybe a
Just DebianVersion
lver Maybe DebianVersion -> Maybe DebianVersion -> Bool
forall a. Ord a => a -> a -> Bool
< Maybe DebianVersion
pver -> [Relation]
compilerDependency [Relation] -> [Relation] -> [Relation]
forall a. [a] -> [a] -> [a]
++ [Relation]
libraryDependency
                   Maybe VersionReq
_ -> [Relation]
libraryDependency [Relation] -> [Relation] -> [Relation]
forall a. [a] -> [a] -> [a]
++ [Relation]
compilerDependency

-- Convert a cabal version to a debian version, adding an epoch number if requested
debianVersion' :: Monad m => PackageName -> Version -> CabalT m DebianVersion
debianVersion' :: PackageName -> Version -> CabalT m DebianVersion
debianVersion' PackageName
name Version
v =
    do CabalInfo
atoms <- StateT CabalInfo m CabalInfo
forall s (m :: * -> *). MonadState s m => m s
get
       DebianVersion -> CabalT m DebianVersion
forall (m :: * -> *) a. Monad m => a -> m a
return (DebianVersion -> CabalT m DebianVersion)
-> DebianVersion -> CabalT m DebianVersion
forall a b. (a -> b) -> a -> b
$ String -> DebianVersion
forall string. ParseDebianVersion string => string -> DebianVersion
parseDebianVersion' (String -> (Int -> String) -> Maybe Int -> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
"" (\ Int
n -> Int -> String
forall a. Show a => a -> String
show Int
n String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
":") (PackageName -> Map PackageName Int -> Maybe Int
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup PackageName
name (Getting (Map PackageName Int) CabalInfo (Map PackageName Int)
-> CabalInfo -> Map PackageName Int
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (Map PackageName Int) CabalInfo (Map PackageName Int)
Lens' CabalInfo (Map PackageName Int)
A.epochMap CabalInfo
atoms)) String -> ShowS
forall a. [a] -> [a] -> [a]
++ Version -> String
forall a. Pretty a => a -> String
prettyShow Version
v)

debianVersion'' :: CabalInfo -> PackageIdentifier -> DebianVersion
debianVersion'' :: CabalInfo -> PackageIdentifier -> DebianVersion
debianVersion'' CabalInfo
atoms PackageIdentifier
i = String -> DebianVersion
forall string. ParseDebianVersion string => string -> DebianVersion
parseDebianVersion' (String -> (Int -> String) -> Maybe Int -> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
"" (\ Int
n -> Int -> String
forall a. Show a => a -> String
show Int
n String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
":") (PackageName -> Map PackageName Int -> Maybe Int
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (PackageIdentifier -> PackageName
pkgName PackageIdentifier
i) (Getting (Map PackageName Int) CabalInfo (Map PackageName Int)
-> CabalInfo -> Map PackageName Int
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (Map PackageName Int) CabalInfo (Map PackageName Int)
Lens' CabalInfo (Map PackageName Int)
A.epochMap CabalInfo
atoms)) String -> ShowS
forall a. [a] -> [a] -> [a]
++ Version -> String
forall a. Pretty a => a -> String
prettyShow (PackageIdentifier -> Version
pkgVersion PackageIdentifier
i))

data Rels a = And {Rels a -> [Rels a]
unAnd :: [Rels a]} | Or {Rels a -> [Rels a]
unOr :: [Rels a]} | Rel' {Rels a -> a
unRel :: a} deriving Int -> Rels a -> ShowS
[Rels a] -> ShowS
Rels a -> String
(Int -> Rels a -> ShowS)
-> (Rels a -> String) -> ([Rels a] -> ShowS) -> Show (Rels a)
forall a. Show a => Int -> Rels a -> ShowS
forall a. Show a => [Rels a] -> ShowS
forall a. Show a => Rels a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Rels a] -> ShowS
$cshowList :: forall a. Show a => [Rels a] -> ShowS
show :: Rels a -> String
$cshow :: forall a. Show a => Rels a -> String
showsPrec :: Int -> Rels a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Rels a -> ShowS
Show

convert' :: Rels a -> [[a]]
convert' :: Rels a -> [[a]]
convert' = (Rels a -> [a]) -> [Rels a] -> [[a]]
forall a b. (a -> b) -> [a] -> [b]
List.map ((Rels a -> a) -> [Rels a] -> [a]
forall a b. (a -> b) -> [a] -> [b]
List.map Rels a -> a
forall a. Rels a -> a
unRel ([Rels a] -> [a]) -> (Rels a -> [Rels a]) -> Rels a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rels a -> [Rels a]
forall a. Rels a -> [Rels a]
unOr) ([Rels a] -> [[a]]) -> (Rels a -> [Rels a]) -> Rels a -> [[a]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rels a -> [Rels a]
forall a. Rels a -> [Rels a]
unAnd (Rels a -> [Rels a]) -> (Rels a -> Rels a) -> Rels a -> [Rels a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rels a -> Rels a
forall a. Rels a -> Rels a
canonical

-- | return and of ors of rel
canonical :: Rels a -> Rels a
canonical :: Rels a -> Rels a
canonical (Rel' a
rel) = [Rels a] -> Rels a
forall a. [Rels a] -> Rels a
And [[Rels a] -> Rels a
forall a. [Rels a] -> Rels a
Or [a -> Rels a
forall a. a -> Rels a
Rel' a
rel]]
canonical (And [Rels a]
rels) = [Rels a] -> Rels a
forall a. [Rels a] -> Rels a
And ([Rels a] -> Rels a) -> [Rels a] -> Rels a
forall a b. (a -> b) -> a -> b
$ (Rels a -> [Rels a]) -> [Rels a] -> [Rels a]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Rels a -> [Rels a]
forall a. Rels a -> [Rels a]
unAnd (Rels a -> [Rels a]) -> (Rels a -> Rels a) -> Rels a -> [Rels a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rels a -> Rels a
forall a. Rels a -> Rels a
canonical) [Rels a]
rels
canonical (Or [Rels a]
rels) = [Rels a] -> Rels a
forall a. [Rels a] -> Rels a
And ([Rels a] -> Rels a)
-> ([[Rels a]] -> [Rels a]) -> [[Rels a]] -> Rels a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Rels a] -> Rels a) -> [[Rels a]] -> [Rels a]
forall a b. (a -> b) -> [a] -> [b]
List.map [Rels a] -> Rels a
forall a. [Rels a] -> Rels a
Or ([[Rels a]] -> Rels a) -> [[Rels a]] -> Rels a
forall a b. (a -> b) -> a -> b
$ (Rels a -> [Rels a]) -> [Rels a] -> [[Rels a]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ((Rels a -> [Rels a]) -> [Rels a] -> [Rels a]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Rels a -> [Rels a]
forall a. Rels a -> [Rels a]
unOr ([Rels a] -> [Rels a])
-> (Rels a -> [Rels a]) -> Rels a -> [Rels a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rels a -> [Rels a]
forall a. Rels a -> [Rels a]
unAnd (Rels a -> [Rels a]) -> (Rels a -> Rels a) -> Rels a -> [Rels a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rels a -> Rels a
forall a. Rels a -> Rels a
canonical) [Rels a]
rels

filterMissing :: Monad m => [[Relation]] -> CabalT m [[Relation]]
filterMissing :: Relations -> CabalT m Relations
filterMissing Relations
rels =
    StateT CabalInfo m CabalInfo
forall s (m :: * -> *). MonadState s m => m s
get StateT CabalInfo m CabalInfo
-> (CabalInfo -> CabalT m Relations) -> CabalT m Relations
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ CabalInfo
atoms -> Relations -> CabalT m Relations
forall (m :: * -> *) a. Monad m => a -> m a
return (Relations -> CabalT m Relations)
-> Relations -> CabalT m Relations
forall a b. (a -> b) -> a -> b
$
    ([Relation] -> Bool) -> Relations -> Relations
forall a. (a -> Bool) -> [a] -> [a]
List.filter ([Relation] -> [Relation] -> Bool
forall a. Eq a => a -> a -> Bool
/= []) (([Relation] -> [Relation]) -> Relations -> Relations
forall a b. (a -> b) -> [a] -> [b]
List.map ((Relation -> Bool) -> [Relation] -> [Relation]
forall a. (a -> Bool) -> [a] -> [a]
List.filter (\ (Rel BinPkgName
name Maybe VersionReq
_ Maybe ArchitectureReq
_) -> Bool -> Bool
not (BinPkgName -> Set BinPkgName -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member BinPkgName
name (Getting (Set BinPkgName) CabalInfo (Set BinPkgName)
-> CabalInfo -> Set BinPkgName
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view ((DebInfo -> Const (Set BinPkgName) DebInfo)
-> CabalInfo -> Const (Set BinPkgName) CabalInfo
Lens' CabalInfo DebInfo
A.debInfo ((DebInfo -> Const (Set BinPkgName) DebInfo)
 -> CabalInfo -> Const (Set BinPkgName) CabalInfo)
-> ((Set BinPkgName -> Const (Set BinPkgName) (Set BinPkgName))
    -> DebInfo -> Const (Set BinPkgName) DebInfo)
-> Getting (Set BinPkgName) CabalInfo (Set BinPkgName)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Set BinPkgName -> Const (Set BinPkgName) (Set BinPkgName))
-> DebInfo -> Const (Set BinPkgName) DebInfo
Lens' DebInfo (Set BinPkgName)
D.missingDependencies) CabalInfo
atoms)))) Relations
rels)