Skip to content

Commit 87a79be

Browse files
committed
Keep fine-grained deps after solver
The crucial change in this commit is the change to PackageFixedDeps to return a ComponentDeps structure, rather than a flat list of dependencies, as long with corresponding changes in ConfiguredPackage and ReadyPackage to accomodate this. We don't actually take _advantage_ of these more fine-grained dependencies yet; any use of depends is now a use of CD.flatDeps . depends but we will :) Note that I have not updated the top-down solver, so in the output of the top-down solver we cheat and pretend that all dependencies are library dependencies.
1 parent 6b77ea2 commit 87a79be

File tree

11 files changed

+80
-46
lines changed

11 files changed

+80
-46
lines changed

cabal-install/Distribution/Client/BuildReports/Storage.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import Distribution.Client.BuildReports.Anonymous (BuildReport)
2828

2929
import Distribution.Client.Types
3030
import qualified Distribution.Client.InstallPlan as InstallPlan
31+
import qualified Distribution.Client.ComponentDeps as CD
3132
import Distribution.Client.InstallPlan
3233
( InstallPlan )
3334

@@ -129,13 +130,13 @@ fromPlanPackage :: Platform -> CompilerId
129130
fromPlanPackage (Platform arch os) comp planPackage = case planPackage of
130131
InstallPlan.Installed (ReadyPackage srcPkg flags _ deps) result
131132
-> Just $ ( BuildReport.new os arch comp
132-
(packageId srcPkg) flags (map packageId deps)
133+
(packageId srcPkg) flags (map packageId (CD.flatDeps deps))
133134
(Right result)
134135
, extractRepo srcPkg)
135136

136137
InstallPlan.Failed (ConfiguredPackage srcPkg flags _ deps) result
137138
-> Just $ ( BuildReport.new os arch comp
138-
(packageId srcPkg) flags (map confSrcId deps)
139+
(packageId srcPkg) flags (map confSrcId (CD.flatDeps deps))
139140
(Left result)
140141
, extractRepo srcPkg )
141142

cabal-install/Distribution/Client/Configure.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import Distribution.Client.SetupWrapper
2929
( setupWrapper, SetupScriptOptions(..), defaultSetupScriptOptions )
3030
import Distribution.Client.Targets
3131
( userToPackageConstraint )
32+
import qualified Distribution.Client.ComponentDeps as CD
3233

3334
import Distribution.Simple.Compiler
3435
( Compiler, CompilerInfo, compilerInfo, PackageDB(..), PackageDBStack )
@@ -236,10 +237,10 @@ configurePackage verbosity platform comp scriptOptions configFlags
236237
-- deps. In the end only one set gets passed to Setup.hs configure,
237238
-- depending on the Cabal version we are talking to.
238239
configConstraints = [ thisPackageVersion (packageId deppkg)
239-
| deppkg <- deps ],
240+
| deppkg <- CD.flatDeps deps ],
240241
configDependencies = [ (packageName (Installed.sourcePackageId deppkg),
241242
Installed.installedPackageId deppkg)
242-
| deppkg <- deps ],
243+
| deppkg <- CD.flatDeps deps ],
243244
-- Use '--exact-configuration' if supported.
244245
configExactConfiguration = toFlag True,
245246
configVerbosity = toFlag verbosity,

cabal-install/Distribution/Client/Dependency/Modular/ConfiguredConversion.hs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import Distribution.System
1313
import Distribution.Client.Dependency.Modular.Configured
1414
import Distribution.Client.Dependency.Modular.Package
1515

16+
import Distribution.Client.ComponentDeps (ComponentDeps)
1617
import qualified Distribution.Client.ComponentDeps as CD
1718

1819
mkPlan :: Platform -> CompilerInfo -> Bool ->
@@ -27,15 +28,15 @@ convCP iidx sidx (CP qpi fa es ds) =
2728
case convPI qpi of
2829
Left pi -> PreExisting $ InstalledPackage
2930
(fromJust $ SI.lookupInstalledPackageId iidx pi)
30-
(map confSrcId ds')
31+
(map confSrcId $ CD.flatDeps ds')
3132
Right pi -> Configured $ ConfiguredPackage
3233
(fromJust $ CI.lookupPackageId sidx pi)
3334
fa
3435
es
3536
ds'
3637
where
37-
ds' :: [ConfiguredId]
38-
ds' = CD.flatDeps $ fmap (map convConfId) ds
38+
ds' :: ComponentDeps [ConfiguredId]
39+
ds' = fmap (map convConfId) ds
3940

4041
convPI :: PI QPN -> Either InstalledPackageId PackageId
4142
convPI (PI _ (I _ (Inst pi))) = Left pi

cabal-install/Distribution/Client/Dependency/TopDown.hs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ import Distribution.Client.Dependency.Types
3333
, Progress(..), foldProgress )
3434

3535
import qualified Distribution.Client.PackageIndex as PackageIndex
36+
import Distribution.Client.ComponentDeps
37+
( ComponentDeps )
38+
import qualified Distribution.Client.ComponentDeps as CD
3639
import Distribution.Client.PackageIndex
3740
( PackageIndex )
3841
import Distribution.Package
@@ -562,7 +565,10 @@ finaliseSelectedPackages pref selected constraints =
562565
finaliseSource mipkg (SemiConfiguredPackage pkg flags stanzas deps) =
563566
InstallPlan.Configured (ConfiguredPackage pkg flags stanzas deps')
564567
where
565-
deps' = map (confId . pickRemaining mipkg) deps
568+
-- We cheat in the cabal solver, and classify all dependencies as
569+
-- library dependencies.
570+
deps' :: ComponentDeps [ConfiguredId]
571+
deps' = CD.fromLibraryDeps $ map (confId . pickRemaining mipkg) deps
566572

567573
-- InstalledOrSource indicates that we either have a source package
568574
-- available, or an installed one, or both. In the case that we have both

cabal-install/Distribution/Client/Dependency/TopDown/Types.hs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@
1010
--
1111
-- Types for the top-down dependency resolver.
1212
-----------------------------------------------------------------------------
13+
{-# LANGUAGE CPP #-}
1314
module Distribution.Client.Dependency.TopDown.Types where
1415

1516
import Distribution.Client.Types
1617
( SourcePackage(..), ReadyPackage(..), InstalledPackage(..)
1718
, OptionalStanza, ConfiguredId(..) )
1819
import Distribution.Client.InstallPlan
1920
( ConfiguredPackage(..), PlanPackage(..) )
21+
import qualified Distribution.Client.ComponentDeps as CD
2022

2123
import Distribution.Package
2224
( PackageIdentifier, Dependency
@@ -113,10 +115,10 @@ instance PackageSourceDeps InstalledPackageEx where
113115
sourceDeps (InstalledPackageEx _ _ deps) = deps
114116

115117
instance PackageSourceDeps ConfiguredPackage where
116-
sourceDeps (ConfiguredPackage _ _ _ deps) = map confSrcId deps
118+
sourceDeps (ConfiguredPackage _ _ _ deps) = map confSrcId $ CD.flatDeps deps
117119

118120
instance PackageSourceDeps ReadyPackage where
119-
sourceDeps (ReadyPackage _ _ _ deps) = map packageId deps
121+
sourceDeps (ReadyPackage _ _ _ deps) = map packageId $ CD.flatDeps deps
120122

121123
instance PackageSourceDeps InstalledPackage where
122124
sourceDeps (InstalledPackage _ deps) = deps

cabal-install/Distribution/Client/Install.hs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ import qualified Distribution.Client.World as World
103103
import qualified Distribution.InstalledPackageInfo as Installed
104104
import Distribution.Client.Compat.ExecutablePath
105105
import Distribution.Client.JobControl
106+
import qualified Distribution.Client.ComponentDeps as CD
106107

107108
import Distribution.Utils.NubList
108109
import Distribution.Simple.Compiler
@@ -563,8 +564,8 @@ packageStatus _comp installedPkgIndex cpkg =
563564
-> [MergeResult PackageIdentifier PackageIdentifier]
564565
changes pkg pkg' = filter changed $
565566
mergeBy (comparing packageName)
566-
(resolveInstalledIds $ Installed.depends pkg) -- deps of installed pkg
567-
(resolveInstalledIds $ depends $ pkg') -- deps of configured pkg
567+
(resolveInstalledIds $ Installed.depends pkg) -- deps of installed pkg
568+
(resolveInstalledIds $ CD.flatDeps (depends pkg')) -- deps of configured pkg
568569

569570
-- convert to source pkg ids via index
570571
resolveInstalledIds :: [InstalledPackageId] -> [PackageIdentifier]
@@ -1191,10 +1192,10 @@ installReadyPackage platform cinfo configFlags
11911192
-- In the end only one set gets passed to Setup.hs configure, depending on
11921193
-- the Cabal version we are talking to.
11931194
configConstraints = [ thisPackageVersion (packageId deppkg)
1194-
| deppkg <- deps ],
1195+
| deppkg <- CD.flatDeps deps ],
11951196
configDependencies = [ (packageName (Installed.sourcePackageId deppkg),
11961197
Installed.installedPackageId deppkg)
1197-
| deppkg <- deps ],
1198+
| deppkg <- CD.flatDeps deps ],
11981199
-- Use '--exact-configuration' if supported.
11991200
configExactConfiguration = toFlag True,
12001201
configBenchmarks = toFlag False,

cabal-install/Distribution/Client/InstallPlan.hs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ import Distribution.Client.PackageUtils
7070
( externalBuildDepends )
7171
import Distribution.Client.PackageIndex
7272
( PackageFixedDeps(..) )
73+
import Distribution.Client.ComponentDeps (ComponentDeps)
74+
import qualified Distribution.Client.ComponentDeps as CD
7375
import Distribution.PackageDescription.Configuration
7476
( finalizePackageDescription )
7577
import Distribution.Simple.PackageIndex
@@ -100,6 +102,7 @@ import Control.Exception
100102
( assert )
101103
import Data.Maybe (catMaybes)
102104
import qualified Data.Map as Map
105+
import qualified Data.Traversable as T
103106

104107
type PlanIndex = PackageIndex PlanPackage
105108

@@ -300,8 +303,8 @@ ready plan = assert check readyPackages
300303
, deps <- maybeToList (hasAllInstalledDeps pkg)
301304
]
302305

303-
hasAllInstalledDeps :: ConfiguredPackage -> Maybe [Installed.InstalledPackageInfo]
304-
hasAllInstalledDeps = mapM isInstalledDep . depends
306+
hasAllInstalledDeps :: ConfiguredPackage -> Maybe (ComponentDeps [Installed.InstalledPackageInfo])
307+
hasAllInstalledDeps = T.mapM (mapM isInstalledDep) . depends
305308

306309
isInstalledDep :: InstalledPackageId -> Maybe Installed.InstalledPackageInfo
307310
isInstalledDep pkgid =
@@ -491,7 +494,7 @@ problems platform cinfo fakeMap indepGoals index =
491494

492495
++ [ PackageStateInvalid pkg pkg'
493496
| pkg <- PackageIndex.allPackages index
494-
, Just pkg' <- map (PlanIndex.fakeLookupInstalledPackageId fakeMap index) (depends pkg)
497+
, Just pkg' <- map (PlanIndex.fakeLookupInstalledPackageId fakeMap index) (CD.flatDeps (depends pkg))
495498
, not (stateDependencyRelation pkg pkg') ]
496499

497500
-- | The graph of packages (nodes) and dependencies (edges) must be acyclic.
@@ -612,31 +615,40 @@ configuredPackageProblems platform cinfo
612615
++ [ MissingFlag flag | OnlyInLeft flag <- mergedFlags ]
613616
++ [ ExtraFlag flag | OnlyInRight flag <- mergedFlags ]
614617
++ [ DuplicateDeps pkgs
615-
| pkgs <- duplicatesBy (comparing packageName) specifiedDeps ]
618+
| pkgs <- CD.flatDeps (fmap (duplicatesBy (comparing packageName)) specifiedDeps) ]
616619
++ [ MissingDep dep | OnlyInLeft dep <- mergedDeps ]
617620
++ [ ExtraDep pkgid | OnlyInRight pkgid <- mergedDeps ]
618621
++ [ InvalidDep dep pkgid | InBoth dep pkgid <- mergedDeps
619622
, not (packageSatisfiesDependency pkgid dep) ]
620623
where
621-
specifiedDeps :: [PackageId]
622-
specifiedDeps = map confSrcId specifiedDeps'
624+
specifiedDeps :: ComponentDeps [PackageId]
625+
specifiedDeps = fmap (map confSrcId) specifiedDeps'
623626

624627
mergedFlags = mergeBy compare
625628
(sort $ map flagName (genPackageFlags (packageDescription pkg)))
626629
(sort $ map fst specifiedFlags)
627630

628-
mergedDeps = mergeBy
629-
(\dep pkgid -> dependencyName dep `compare` packageName pkgid)
630-
(sortBy (comparing dependencyName) requiredDeps)
631-
(sortBy (comparing packageName) specifiedDeps)
632-
633631
packageSatisfiesDependency
634632
(PackageIdentifier name version)
635633
(Dependency name' versionRange) = assert (name == name') $
636634
version `withinRange` versionRange
637635

638636
dependencyName (Dependency name _) = name
639637

638+
mergedDeps :: [MergeResult Dependency PackageId]
639+
mergedDeps = mergeDeps requiredDeps (CD.flatDeps specifiedDeps)
640+
641+
mergeDeps :: [Dependency] -> [PackageId] -> [MergeResult Dependency PackageId]
642+
mergeDeps required specified =
643+
mergeBy
644+
(\dep pkgid -> dependencyName dep `compare` packageName pkgid)
645+
(sortBy (comparing dependencyName) required)
646+
(sortBy (comparing packageName) specified)
647+
648+
-- TODO: It would be nicer to use PackageDeps here so we can be more precise
649+
-- in our checks. That's a bit tricky though, as this currently relies on
650+
-- the 'buildDepends' field of 'PackageDescription'. (OTOH, that field is
651+
-- deprecated and should be removed anyway.)
640652
requiredDeps :: [Dependency]
641653
requiredDeps =
642654
--TODO: use something lower level than finalizePackageDescription

cabal-install/Distribution/Client/InstallSymlink.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import Distribution.Package
4848
import Distribution.Compiler
4949
( CompilerId(..) )
5050
import qualified Distribution.PackageDescription as PackageDescription
51+
import qualified Distribution.Client.ComponentDeps as CD
5152
import Distribution.PackageDescription
5253
( PackageDescription )
5354
import Distribution.PackageDescription.Configuration
@@ -122,7 +123,7 @@ symlinkBinaries comp configFlags installFlags plan =
122123
| (ReadyPackage _ _flags _ deps, pkg, exe) <- exes
123124
, let pkgid = packageId pkg
124125
pkg_key = mkPackageKey (packageKeySupported comp) pkgid
125-
(map Installed.packageKey deps) []
126+
(map Installed.packageKey (CD.flatDeps deps)) []
126127
publicExeName = PackageDescription.exeName exe
127128
privateExeName = prefix ++ publicExeName ++ suffix
128129
prefix = substTemplate pkgid pkg_key prefixTemplate

cabal-install/Distribution/Client/PackageIndex.hs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ import Distribution.InstalledPackageInfo
7070
import Distribution.Simple.Utils
7171
( lowercase, comparing )
7272

73+
import Distribution.Client.ComponentDeps (ComponentDeps)
74+
import qualified Distribution.Client.ComponentDeps as CD
75+
7376
-- | Subclass of packages that have specific versioned dependencies.
7477
--
7578
-- So for example a not-yet-configured package has dependencies on version
@@ -78,10 +81,10 @@ import Distribution.Simple.Utils
7881
-- dependency graphs) only make sense on this subclass of package types.
7982
--
8083
class Package pkg => PackageFixedDeps pkg where
81-
depends :: pkg -> [InstalledPackageId]
84+
depends :: pkg -> ComponentDeps [InstalledPackageId]
8285

8386
instance PackageFixedDeps (InstalledPackageInfo_ str) where
84-
depends info = installedDepends info
87+
depends = CD.fromInstalled . installedDepends
8588

8689
-- | The collection of information about packages from one or more 'PackageDB's.
8790
--

cabal-install/Distribution/Client/PlanIndex.hs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ import Distribution.Package
4040
import Distribution.Version
4141
( Version )
4242

43+
import Distribution.Client.ComponentDeps (ComponentDeps)
44+
import qualified Distribution.Client.ComponentDeps as CD
4345
import Distribution.Client.PackageIndex
4446
( PackageFixedDeps(..) )
4547
import Distribution.Simple.PackageIndex
@@ -84,8 +86,8 @@ type FakeMap = Map InstalledPackageId InstalledPackageId
8486
-- | Variant of `depends` which accepts a `FakeMap`
8587
--
8688
-- Analogous to `fakeInstalledDepends`. See Note [FakeMap].
87-
fakeDepends :: PackageFixedDeps pkg => FakeMap -> pkg -> [InstalledPackageId]
88-
fakeDepends fakeMap = map resolveFakeId . depends
89+
fakeDepends :: PackageFixedDeps pkg => FakeMap -> pkg -> ComponentDeps [InstalledPackageId]
90+
fakeDepends fakeMap = fmap (map resolveFakeId) . depends
8991
where
9092
resolveFakeId :: InstalledPackageId -> InstalledPackageId
9193
resolveFakeId ipid = Map.findWithDefault ipid ipid fakeMap
@@ -109,7 +111,7 @@ brokenPackages fakeMap index =
109111
[ (pkg, missing)
110112
| pkg <- allPackages index
111113
, let missing =
112-
[ pkg' | pkg' <- depends pkg
114+
[ pkg' | pkg' <- CD.flatDeps (depends pkg)
113115
, isNothing (fakeLookupInstalledPackageId fakeMap index pkg') ]
114116
, not (null missing) ]
115117

@@ -186,7 +188,7 @@ dependencyInconsistencies' fakeMap index =
186188
| -- For each package @pkg@
187189
pkg <- allPackages index
188190
-- Find out which @ipid@ @pkg@ depends on
189-
, ipid <- fakeDepends fakeMap pkg
191+
, ipid <- CD.flatDeps (fakeDepends fakeMap pkg)
190192
-- And look up those @ipid@ (i.e., @ipid@ is the ID of @dep@)
191193
, Just dep <- [fakeLookupInstalledPackageId fakeMap index ipid]
192194
]
@@ -202,8 +204,8 @@ dependencyInconsistencies' fakeMap index =
202204
reallyIsInconsistent [p1, p2] =
203205
let pid1 = installedPackageId p1
204206
pid2 = installedPackageId p2
205-
in Map.findWithDefault pid1 pid1 fakeMap `notElem` fakeDepends fakeMap p2
206-
&& Map.findWithDefault pid2 pid2 fakeMap `notElem` fakeDepends fakeMap p1
207+
in Map.findWithDefault pid1 pid1 fakeMap `notElem` CD.flatDeps (fakeDepends fakeMap p2)
208+
&& Map.findWithDefault pid2 pid2 fakeMap `notElem` CD.flatDeps (fakeDepends fakeMap p1)
207209
reallyIsInconsistent _ = True
208210

209211

@@ -223,7 +225,7 @@ dependencyCycles :: (PackageFixedDeps pkg, HasInstalledPackageId pkg)
223225
dependencyCycles fakeMap index =
224226
[ vs | Graph.CyclicSCC vs <- Graph.stronglyConnComp adjacencyList ]
225227
where
226-
adjacencyList = [ (pkg, installedPackageId pkg, fakeDepends fakeMap pkg)
228+
adjacencyList = [ (pkg, installedPackageId pkg, CD.flatDeps (fakeDepends fakeMap pkg))
227229
| pkg <- allPackages index ]
228230

229231

@@ -254,7 +256,7 @@ dependencyClosure fakeMap index pkgids0 = case closure mempty [] pkgids0 of
254256
Just _ -> closure completed failed pkgids
255257
Nothing -> closure completed' failed pkgids'
256258
where completed' = insert pkg completed
257-
pkgids' = depends pkg ++ pkgids
259+
pkgids' = CD.flatDeps (depends pkg) ++ pkgids
258260

259261

260262
topologicalOrder :: (PackageFixedDeps pkg, HasInstalledPackageId pkg)
@@ -320,5 +322,5 @@ dependencyGraph fakeMap index = (graph, vertexToPkg, idToVertex)
320322
resolve pid = Map.findWithDefault pid pid fakeMap
321323
edgesFrom pkg = ( ()
322324
, resolve (installedPackageId pkg)
323-
, fakeDepends fakeMap pkg
325+
, CD.flatDeps (fakeDepends fakeMap pkg)
324326
)

0 commit comments

Comments
 (0)