1 -----------------------------------------------------------------------------
3 -----------------------------------------------------------------------------
6 -- Module : Distribution.Client.Dependency
7 -- Copyright : (c) David Himmelstrup 2005,
12 -- Maintainer : cabal-devel@gmail.com
13 -- Stability : provisional
14 -- Portability : portable
16 -- Top level interface to dependency resolution.
17 module Distribution
.Client
.Dependency
18 ( -- * The main package dependency resolver
24 -- * Alternate, simple resolver that does not do dependencies recursively
25 , resolveWithoutDependencies
27 -- * Constructing resolver policies
28 , PackageProperty
(..)
29 , PackageConstraint
(..)
31 , PackagesPreferenceDefault
(..)
32 , PackagePreference
(..)
36 , standardInstallPolicy
37 , PackageSpecifier
(..)
39 -- ** Extra policy options
46 , setPreferenceDefault
49 , setFineGrainedConflicts
50 , setMinimizeConflictSet
55 , setAllowBootLibInstalls
58 , setEnableBackjumping
64 , addDefaultSetupDependencies
65 , addSetupCabalMinVersionConstraint
66 , addSetupCabalMaxVersionConstraint
69 import Distribution
.Client
.Compat
.Prelude
71 import Distribution
.Client
.Dependency
.Types
72 ( PackagesPreferenceDefault
(..)
74 import Distribution
.Client
.SolverInstallPlan
(SolverInstallPlan
)
75 import qualified Distribution
.Client
.SolverInstallPlan
as SolverInstallPlan
76 import Distribution
.Client
.Types
79 , PackageSpecifier
(..)
82 , RelaxDepSubject
(..)
85 , SourcePackageDb
(SourcePackageDb
)
87 , UnresolvedSourcePackage
89 , pkgSpecifierConstraints
92 import Distribution
.Client
.Utils
97 import qualified Distribution
.Compat
.Graph
as Graph
98 import Distribution
.Compiler
101 import Distribution
.Package
104 , PackageIdentifier
(PackageIdentifier
)
110 import qualified Distribution
.PackageDescription
as PD
111 import Distribution
.PackageDescription
.Configuration
114 import qualified Distribution
.PackageDescription
.Configuration
as PD
115 import Distribution
.Simple
.PackageIndex
(InstalledPackageIndex
)
116 import qualified Distribution
.Simple
.PackageIndex
as InstalledPackageIndex
117 import Distribution
.Simple
.Setup
120 import Distribution
.Solver
.Modular
121 ( PruneAfterFirstSuccess
(..)
125 import Distribution
.System
128 import Distribution
.Types
.Dependency
129 import Distribution
.Verbosity
132 import Distribution
.Version
134 import Distribution
.Solver
.Types
.ComponentDeps
(ComponentDeps
)
135 import qualified Distribution
.Solver
.Types
.ComponentDeps
as CD
136 import Distribution
.Solver
.Types
.ConstraintSource
137 import Distribution
.Solver
.Types
.DependencyResolver
138 import Distribution
.Solver
.Types
.InstalledPreference
as Preference
139 import Distribution
.Solver
.Types
.LabeledPackageConstraint
140 import Distribution
.Solver
.Types
.OptionalStanza
141 import Distribution
.Solver
.Types
.PackageConstraint
142 import qualified Distribution
.Solver
.Types
.PackageIndex
as PackageIndex
143 import Distribution
.Solver
.Types
.PackagePath
144 import Distribution
.Solver
.Types
.PackagePreferences
145 import Distribution
.Solver
.Types
.PkgConfigDb
(PkgConfigDb
)
146 import Distribution
.Solver
.Types
.Progress
147 import Distribution
.Solver
.Types
.ResolverPackage
148 import Distribution
.Solver
.Types
.Settings
149 import Distribution
.Solver
.Types
.SolverId
150 import Distribution
.Solver
.Types
.SolverPackage
151 import Distribution
.Solver
.Types
.SourcePackage
152 import Distribution
.Solver
.Types
.Variable
154 import Control
.Exception
160 import qualified Data
.Map
as Map
161 import qualified Data
.Set
as Set
163 -- ------------------------------------------------------------
165 -- * High level planner policy
167 -- ------------------------------------------------------------
169 -- | The set of parameters to the dependency resolver. These parameters are
170 -- relatively low level but many kinds of high level policies can be
171 -- implemented in terms of adjustments to the parameters.
172 data DepResolverParams
= DepResolverParams
173 { depResolverTargets
:: Set PackageName
174 , depResolverConstraints
:: [LabeledPackageConstraint
]
175 , depResolverPreferences
:: [PackagePreference
]
176 , depResolverPreferenceDefault
:: PackagesPreferenceDefault
177 , depResolverInstalledPkgIndex
:: InstalledPackageIndex
178 , depResolverSourcePkgIndex
:: PackageIndex
.PackageIndex UnresolvedSourcePackage
179 , depResolverReorderGoals
:: ReorderGoals
180 , depResolverCountConflicts
:: CountConflicts
181 , depResolverFineGrainedConflicts
:: FineGrainedConflicts
182 , depResolverMinimizeConflictSet
:: MinimizeConflictSet
183 , depResolverIndependentGoals
:: IndependentGoals
184 , depResolverAvoidReinstalls
:: AvoidReinstalls
185 , depResolverShadowPkgs
:: ShadowPkgs
186 , depResolverStrongFlags
:: StrongFlags
187 , depResolverAllowBootLibInstalls
:: AllowBootLibInstalls
188 -- ^ Whether to allow base and its dependencies to be installed.
189 , depResolverOnlyConstrained
:: OnlyConstrained
190 -- ^ Whether to only allow explicitly constrained packages plus
191 -- goals or to allow any package.
192 , depResolverMaxBackjumps
:: Maybe Int
193 , depResolverEnableBackjumping
:: EnableBackjumping
194 , depResolverSolveExecutables
:: SolveExecutables
195 -- ^ Whether or not to solve for dependencies on executables.
196 -- This should be true, except in the legacy code path where
197 -- we can't tell if an executable has been installed or not,
198 -- so we shouldn't solve for them. See #3875.
199 , depResolverGoalOrder
:: Maybe (Variable QPN
-> Variable QPN
-> Ordering)
200 -- ^ Function to override the solver's goal-ordering heuristics.
201 , depResolverVerbosity
:: Verbosity
204 showDepResolverParams
:: DepResolverParams
-> String
205 showDepResolverParams p
=
207 ++ intercalate
", " (map prettyShow
$ Set
.toList
(depResolverTargets p
))
210 (("\n " ++) . showLabeledConstraint
)
211 (depResolverConstraints p
)
214 (("\n " ++) . showPackagePreference
)
215 (depResolverPreferences p
)
217 ++ show (depResolverPreferenceDefault p
)
218 ++ "\nreorder goals: "
219 ++ show (asBool
(depResolverReorderGoals p
))
220 ++ "\ncount conflicts: "
221 ++ show (asBool
(depResolverCountConflicts p
))
222 ++ "\nfine grained conflicts: "
223 ++ show (asBool
(depResolverFineGrainedConflicts p
))
224 ++ "\nminimize conflict set: "
225 ++ show (asBool
(depResolverMinimizeConflictSet p
))
226 ++ "\nindependent goals: "
227 ++ show (asBool
(depResolverIndependentGoals p
))
228 ++ "\navoid reinstalls: "
229 ++ show (asBool
(depResolverAvoidReinstalls p
))
230 ++ "\nshadow packages: "
231 ++ show (asBool
(depResolverShadowPkgs p
))
232 ++ "\nstrong flags: "
233 ++ show (asBool
(depResolverStrongFlags p
))
234 ++ "\nallow boot library installs: "
235 ++ show (asBool
(depResolverAllowBootLibInstalls p
))
236 ++ "\nonly constrained packages: "
237 ++ show (depResolverOnlyConstrained p
)
238 ++ "\nmax backjumps: "
242 (depResolverMaxBackjumps p
)
244 showLabeledConstraint
:: LabeledPackageConstraint
-> String
245 showLabeledConstraint
(LabeledPackageConstraint pc src
) =
246 showPackageConstraint pc
++ " (" ++ showConstraintSource src
++ ")"
248 -- | A package selection preference for a particular package.
250 -- Preferences are soft constraints that the dependency resolver should try to
251 -- respect where possible. It is not specified if preferences on some packages
252 -- are more important than others.
253 data PackagePreference
254 = -- | A suggested constraint on the version number.
255 PackageVersionPreference PackageName VersionRange
256 |
-- | If we prefer versions of packages that are already installed.
257 PackageInstalledPreference PackageName InstalledPreference
258 |
-- | If we would prefer to enable these optional stanzas
259 -- (i.e. test suites and/or benchmarks)
260 PackageStanzasPreference PackageName
[OptionalStanza
]
262 -- | Provide a textual representation of a package preference
263 -- for debugging purposes.
264 showPackagePreference
:: PackagePreference
-> String
265 showPackagePreference
(PackageVersionPreference pn vr
) =
266 prettyShow pn
++ " " ++ prettyShow
(simplifyVersionRange vr
)
267 showPackagePreference
(PackageInstalledPreference pn ip
) =
268 prettyShow pn
++ " " ++ show ip
269 showPackagePreference
(PackageStanzasPreference pn st
) =
270 prettyShow pn
++ " " ++ show st
272 basicDepResolverParams
273 :: InstalledPackageIndex
274 -> PackageIndex
.PackageIndex UnresolvedSourcePackage
276 basicDepResolverParams installedPkgIndex sourcePkgIndex
=
278 { depResolverTargets
= Set
.empty
279 , depResolverConstraints
= []
280 , depResolverPreferences
= []
281 , depResolverPreferenceDefault
= PreferLatestForSelected
282 , depResolverInstalledPkgIndex
= installedPkgIndex
283 , depResolverSourcePkgIndex
= sourcePkgIndex
284 , depResolverReorderGoals
= ReorderGoals
False
285 , depResolverCountConflicts
= CountConflicts
True
286 , depResolverFineGrainedConflicts
= FineGrainedConflicts
True
287 , depResolverMinimizeConflictSet
= MinimizeConflictSet
False
288 , depResolverIndependentGoals
= IndependentGoals
False
289 , depResolverAvoidReinstalls
= AvoidReinstalls
False
290 , depResolverShadowPkgs
= ShadowPkgs
False
291 , depResolverStrongFlags
= StrongFlags
False
292 , depResolverAllowBootLibInstalls
= AllowBootLibInstalls
False
293 , depResolverOnlyConstrained
= OnlyConstrainedNone
294 , depResolverMaxBackjumps
= Nothing
295 , depResolverEnableBackjumping
= EnableBackjumping
True
296 , depResolverSolveExecutables
= SolveExecutables
True
297 , depResolverGoalOrder
= Nothing
298 , depResolverVerbosity
= normal
305 addTargets extraTargets params
=
307 { depResolverTargets
= Set
.fromList extraTargets `Set
.union` depResolverTargets params
311 :: [LabeledPackageConstraint
]
314 addConstraints extraConstraints params
=
316 { depResolverConstraints
=
318 ++ depResolverConstraints params
322 :: [PackagePreference
]
325 addPreferences extraPreferences params
=
327 { depResolverPreferences
=
329 ++ depResolverPreferences params
333 :: PackagesPreferenceDefault
336 setPreferenceDefault preferenceDefault params
=
338 { depResolverPreferenceDefault
= preferenceDefault
341 setReorderGoals
:: ReorderGoals
-> DepResolverParams
-> DepResolverParams
342 setReorderGoals reorder params
=
344 { depResolverReorderGoals
= reorder
347 setCountConflicts
:: CountConflicts
-> DepResolverParams
-> DepResolverParams
348 setCountConflicts count params
=
350 { depResolverCountConflicts
= count
353 setFineGrainedConflicts
:: FineGrainedConflicts
-> DepResolverParams
-> DepResolverParams
354 setFineGrainedConflicts fineGrained params
=
356 { depResolverFineGrainedConflicts
= fineGrained
359 setMinimizeConflictSet
:: MinimizeConflictSet
-> DepResolverParams
-> DepResolverParams
360 setMinimizeConflictSet minimize params
=
362 { depResolverMinimizeConflictSet
= minimize
365 setIndependentGoals
:: IndependentGoals
-> DepResolverParams
-> DepResolverParams
366 setIndependentGoals indep params
=
368 { depResolverIndependentGoals
= indep
371 setAvoidReinstalls
:: AvoidReinstalls
-> DepResolverParams
-> DepResolverParams
372 setAvoidReinstalls avoid params
=
374 { depResolverAvoidReinstalls
= avoid
377 setShadowPkgs
:: ShadowPkgs
-> DepResolverParams
-> DepResolverParams
378 setShadowPkgs shadow params
=
380 { depResolverShadowPkgs
= shadow
383 setStrongFlags
:: StrongFlags
-> DepResolverParams
-> DepResolverParams
384 setStrongFlags sf params
=
386 { depResolverStrongFlags
= sf
389 setAllowBootLibInstalls
:: AllowBootLibInstalls
-> DepResolverParams
-> DepResolverParams
390 setAllowBootLibInstalls i params
=
392 { depResolverAllowBootLibInstalls
= i
395 setOnlyConstrained
:: OnlyConstrained
-> DepResolverParams
-> DepResolverParams
396 setOnlyConstrained i params
=
398 { depResolverOnlyConstrained
= i
401 setMaxBackjumps
:: Maybe Int -> DepResolverParams
-> DepResolverParams
402 setMaxBackjumps n params
=
404 { depResolverMaxBackjumps
= n
407 setEnableBackjumping
:: EnableBackjumping
-> DepResolverParams
-> DepResolverParams
408 setEnableBackjumping b params
=
410 { depResolverEnableBackjumping
= b
413 setSolveExecutables
:: SolveExecutables
-> DepResolverParams
-> DepResolverParams
414 setSolveExecutables b params
=
416 { depResolverSolveExecutables
= b
420 :: Maybe (Variable QPN
-> Variable QPN
-> Ordering)
423 setGoalOrder
order params
=
425 { depResolverGoalOrder
= order
428 setSolverVerbosity
:: Verbosity
-> DepResolverParams
-> DepResolverParams
429 setSolverVerbosity verbosity params
=
431 { depResolverVerbosity
= verbosity
434 -- | Some packages are specific to a given compiler version and should never be
436 dontInstallNonReinstallablePackages
:: DepResolverParams
-> DepResolverParams
437 dontInstallNonReinstallablePackages params
=
438 addConstraints extraConstraints params
441 [ LabeledPackageConstraint
442 (PackageConstraint
(ScopeAnyQualifier pkgname
) PackagePropertyInstalled
)
443 ConstraintSourceNonReinstallablePackage
444 | pkgname
<- nonReinstallablePackages
447 -- | The set of non-reinstallable packages includes those which cannot be
448 -- rebuilt using a GHC installation and Hackage-published source distribution.
449 -- There are a few reasons why this might be true:
451 -- * the package overrides its unit ID (e.g. with ghc's @-this-unit-id@ flag),
452 -- which can result in multiple indistinguishable packages (having potentially
453 -- different ABIs) with the same unit ID.
455 -- * the package contains definitions of wired-in declarations which tie
456 -- it to a particular compiler (e.g. we can't build link against
457 -- @base-4.18.0.0@ using GHC 9.6.1).
459 -- * the package does not have a complete (that is, buildable) source distribution.
460 -- For instance, some packages provided by GHC rely on files outside of the
461 -- source tree generated by GHC's build system.
462 nonReinstallablePackages
:: [PackageName
]
463 nonReinstallablePackages
=
464 [ mkPackageName
"base"
465 , mkPackageName
"ghc-bignum"
466 , mkPackageName
"ghc-prim"
467 , mkPackageName
"ghc"
468 , mkPackageName
"integer-gmp"
469 , mkPackageName
"integer-simple"
470 , mkPackageName
"template-haskell"
474 :: [UnresolvedSourcePackage
]
477 addSourcePackages pkgs params
=
479 { depResolverSourcePkgIndex
=
481 (flip PackageIndex
.insert)
482 (depResolverSourcePkgIndex params
)
486 hideInstalledPackagesSpecificBySourcePackageId
490 hideInstalledPackagesSpecificBySourcePackageId pkgids params
=
491 -- TODO: this should work using exclude constraints instead
493 { depResolverInstalledPkgIndex
=
495 (flip InstalledPackageIndex
.deleteSourcePackageId
)
496 (depResolverInstalledPkgIndex params
)
500 hideInstalledPackagesAllVersions
504 hideInstalledPackagesAllVersions pkgnames params
=
505 -- TODO: this should work using exclude constraints instead
507 { depResolverInstalledPkgIndex
=
509 (flip InstalledPackageIndex
.deletePackageName
)
510 (depResolverInstalledPkgIndex params
)
514 -- | Remove upper bounds in dependencies using the policy specified by the
515 -- 'AllowNewer' argument (all/some/none).
517 -- Note: It's important to apply 'removeUpperBounds' after
518 -- 'addSourcePackages'. Otherwise, the packages inserted by
519 -- 'addSourcePackages' won't have upper bounds in dependencies relaxed.
520 removeUpperBounds
:: AllowNewer
-> DepResolverParams
-> DepResolverParams
521 removeUpperBounds
(AllowNewer relDeps
) = removeBounds RelaxUpper relDeps
523 -- | Dual of 'removeUpperBounds'
524 removeLowerBounds
:: AllowOlder
-> DepResolverParams
-> DepResolverParams
525 removeLowerBounds
(AllowOlder relDeps
) = removeBounds RelaxLower relDeps
527 data RelaxKind
= RelaxLower | RelaxUpper
529 -- | Common internal implementation of 'removeLowerBounds'/'removeUpperBounds'
530 removeBounds
:: RelaxKind
-> RelaxDeps
-> DepResolverParams
-> DepResolverParams
531 removeBounds _ rd params |
not (isRelaxDeps rd
) = params
-- no-op optimisation
532 removeBounds relKind relDeps params
=
534 { depResolverSourcePkgIndex
= sourcePkgIndex
'
537 sourcePkgIndex
' :: PackageIndex
.PackageIndex UnresolvedSourcePackage
538 sourcePkgIndex
' = relaxDeps
<$> depResolverSourcePkgIndex params
540 relaxDeps
:: UnresolvedSourcePackage
-> UnresolvedSourcePackage
543 { srcpkgDescription
= relaxPackageDeps relKind relDeps
(srcpkgDescription srcPkg
)
546 -- | Relax the dependencies of this package if needed.
548 -- Helper function used by 'removeBounds'
552 -> PD
.GenericPackageDescription
553 -> PD
.GenericPackageDescription
554 relaxPackageDeps _ rd gpd |
not (isRelaxDeps rd
) = gpd
-- subsumed by no-op case in 'removeBounds'
555 relaxPackageDeps relKind RelaxDepsAll gpd
= PD
.transformAllBuildDepends relaxAll gpd
557 relaxAll
:: Dependency
-> Dependency
558 relaxAll
(Dependency pkgName verRange cs
) =
559 Dependency pkgName
(removeBound relKind RelaxDepModNone verRange
) cs
560 relaxPackageDeps relKind
(RelaxDepsSome depsToRelax0
) gpd
=
561 PD
.transformAllBuildDepends relaxSome gpd
563 thisPkgName
= packageName gpd
564 thisPkgId
= packageId gpd
565 depsToRelax
= Map
.fromList
$ mapMaybe f depsToRelax0
567 f
:: RelaxedDep
-> Maybe (RelaxDepSubject
, RelaxDepMod
)
568 f
(RelaxedDep scope rdm p
) = case scope
of
569 RelaxDepScopeAll
-> Just
(p
, rdm
)
570 RelaxDepScopePackage p0
571 | p0
== thisPkgName
-> Just
(p
, rdm
)
572 |
otherwise -> Nothing
573 RelaxDepScopePackageId p0
574 | p0
== thisPkgId
-> Just
(p
, rdm
)
575 |
otherwise -> Nothing
577 relaxSome
:: Dependency
-> Dependency
578 relaxSome d
@(Dependency depName verRange cs
)
579 | Just relMod
<- Map
.lookup RelaxDepSubjectAll depsToRelax
=
580 -- a '*'-subject acts absorbing, for consistency with
581 -- the 'Semigroup RelaxDeps' instance
582 Dependency depName
(removeBound relKind relMod verRange
) cs
583 | Just relMod
<- Map
.lookup (RelaxDepSubjectPkg depName
) depsToRelax
=
584 Dependency depName
(removeBound relKind relMod verRange
) cs
585 |
otherwise = d
-- no-op
587 -- | Internal helper for 'relaxPackageDeps'
588 removeBound
:: RelaxKind
-> RelaxDepMod
-> VersionRange
-> VersionRange
589 removeBound RelaxLower RelaxDepModNone
= removeLowerBound
590 removeBound RelaxUpper RelaxDepModNone
= removeUpperBound
591 removeBound RelaxLower RelaxDepModCaret
= transformCaretLower
592 removeBound RelaxUpper RelaxDepModCaret
= transformCaretUpper
594 -- | Supply defaults for packages without explicit Setup dependencies
596 -- Note: It's important to apply 'addDefaultSetupDepends' after
597 -- 'addSourcePackages'. Otherwise, the packages inserted by
598 -- 'addSourcePackages' won't have upper bounds in dependencies relaxed.
599 addDefaultSetupDependencies
600 :: (UnresolvedSourcePackage
-> Maybe [Dependency
])
603 addDefaultSetupDependencies defaultSetupDeps params
=
605 { depResolverSourcePkgIndex
=
606 fmap applyDefaultSetupDeps
(depResolverSourcePkgIndex params
)
609 applyDefaultSetupDeps
:: UnresolvedSourcePackage
-> UnresolvedSourcePackage
610 applyDefaultSetupDeps srcpkg
=
612 { srcpkgDescription
=
614 { PD
.packageDescription
=
616 { PD
.setupBuildInfo
=
617 case PD
.setupBuildInfo pkgdesc
of
619 Nothing
-> case defaultSetupDeps srcpkg
of
625 { PD
.defaultSetupDepends
= True
626 , PD
.setupDepends
= deps
628 |
otherwise -> Nothing
633 isCustom
= PD
.buildType pkgdesc
== PD
.Custom
634 gpkgdesc
= srcpkgDescription srcpkg
635 pkgdesc
= PD
.packageDescription gpkgdesc
637 -- | If a package has a custom setup then we need to add a setup-depends
639 addSetupCabalMinVersionConstraint
643 addSetupCabalMinVersionConstraint minVersion
=
645 [ LabeledPackageConstraint
647 (ScopeAnySetupQualifier cabalPkgname
)
648 (PackagePropertyVersion
$ orLaterVersion minVersion
)
650 ConstraintSetupCabalMinVersion
653 cabalPkgname
= mkPackageName
"Cabal"
655 -- | Variant of 'addSetupCabalMinVersionConstraint' which sets an
656 -- upper bound on @setup.Cabal@ labeled with 'ConstraintSetupCabalMaxVersion'.
657 addSetupCabalMaxVersionConstraint
661 addSetupCabalMaxVersionConstraint maxVersion
=
663 [ LabeledPackageConstraint
665 (ScopeAnySetupQualifier cabalPkgname
)
666 (PackagePropertyVersion
$ earlierVersion maxVersion
)
668 ConstraintSetupCabalMaxVersion
671 cabalPkgname
= mkPackageName
"Cabal"
673 upgradeDependencies
:: DepResolverParams
-> DepResolverParams
674 upgradeDependencies
= setPreferenceDefault PreferAllLatest
676 reinstallTargets
:: DepResolverParams
-> DepResolverParams
677 reinstallTargets params
=
678 hideInstalledPackagesAllVersions
(Set
.toList
$ depResolverTargets params
) params
680 -- | A basic solver policy on which all others are built.
682 :: InstalledPackageIndex
684 -> [PackageSpecifier UnresolvedSourcePackage
]
688 (SourcePackageDb sourcePkgIndex sourcePkgPrefs
)
691 [ PackageVersionPreference name ver
692 |
(name
, ver
) <- Map
.toList sourcePkgPrefs
695 (concatMap pkgSpecifierConstraints pkgSpecifiers
)
697 (map pkgSpecifierTarget pkgSpecifiers
)
698 . hideInstalledPackagesSpecificBySourcePackageId
699 [packageId pkg | SpecificSourcePackage pkg
<- pkgSpecifiers
]
701 [pkg | SpecificSourcePackage pkg
<- pkgSpecifiers
]
702 $ basicDepResolverParams
706 -- | The policy used by all the standard commands, install, fetch, freeze etc
707 -- (but not the v2-build and related commands).
709 -- It extends the 'basicInstallPolicy' with a policy on setup deps.
710 standardInstallPolicy
711 :: InstalledPackageIndex
713 -> [PackageSpecifier UnresolvedSourcePackage
]
715 standardInstallPolicy installedPkgIndex sourcePkgDb pkgSpecifiers
=
716 addDefaultSetupDependencies mkDefaultSetupDeps
$
722 -- Force Cabal >= 1.24 dep when the package is affected by #3199.
723 mkDefaultSetupDeps
:: UnresolvedSourcePackage
-> Maybe [Dependency
]
724 mkDefaultSetupDeps srcpkg
726 Just
[Dependency
(mkPackageName
"Cabal") (orLaterVersion
$ mkVersion
[1, 24]) mainLibSet
]
727 |
otherwise = Nothing
729 gpkgdesc
= srcpkgDescription srcpkg
730 pkgdesc
= PD
.packageDescription gpkgdesc
731 bt
= PD
.buildType pkgdesc
732 affected
= bt
== PD
.Custom
&& hasBuildableFalse gpkgdesc
734 -- Does this package contain any components with non-empty 'build-depends'
735 -- and a 'buildable' field that could potentially be set to 'False'? False
736 -- positives are possible.
737 hasBuildableFalse
:: PD
.GenericPackageDescription
-> Bool
738 hasBuildableFalse gpkg
=
739 not (all alwaysTrue
(zipWith PD
.cOr buildableConditions noDepConditions
))
741 buildableConditions
= PD
.extractConditions PD
.buildable gpkg
744 (null . PD
.targetBuildDepends
)
746 alwaysTrue
(PD
.Lit
True) = True
749 -- ------------------------------------------------------------
751 -- * Interface to the standard resolver
753 -- ------------------------------------------------------------
755 runSolver
:: SolverConfig
-> DependencyResolver UnresolvedPkgLoc
756 runSolver
= modularResolver
758 -- | Run the dependency solver.
760 -- Since this is potentially an expensive operation, the result is wrapped in a
761 -- a 'Progress' structure that can be unfolded to provide progress information,
762 -- logging messages and the final result or an error.
768 -> Progress
String String SolverInstallPlan
769 resolveDependencies platform comp pkgConfigDB params
=
770 Step
(showDepResolverParams finalparams
) $
771 fmap (validateSolverResult platform comp indGoals
) $
788 (PruneAfterFirstSuccess
False)
799 finalparams
@( DepResolverParams
822 if asBool
(depResolverAllowBootLibInstalls params
)
824 else dontInstallNonReinstallablePackages params
826 preferences
:: PackageName
-> PackagePreferences
827 preferences
= interpretPackagesPreference targets defpref prefs
829 -- | Give an interpretation to the global 'PackagesPreference' as
830 -- specific per-package 'PackageVersionPreference'.
831 interpretPackagesPreference
833 -> PackagesPreferenceDefault
834 -> [PackagePreference
]
835 -> (PackageName
-> PackagePreferences
)
836 interpretPackagesPreference selected defaultPref prefs
=
839 (versionPref pkgname
)
840 (installPref pkgname
)
841 (stanzasPref pkgname
)
843 versionPref
:: PackageName
-> [VersionRange
]
844 versionPref pkgname
=
845 fromMaybe [anyVersion
] (Map
.lookup pkgname versionPrefs
)
850 | PackageVersionPreference pkgname pref
<- prefs
853 installPref
:: PackageName
-> InstalledPreference
854 installPref pkgname
=
855 fromMaybe (installPrefDefault pkgname
) (Map
.lookup pkgname installPrefs
)
859 | PackageInstalledPreference pkgname pref
<- prefs
861 installPrefDefault
= case defaultPref
of
862 PreferAllLatest
-> const Preference
.PreferLatest
863 PreferAllOldest
-> const Preference
.PreferOldest
864 PreferAllInstalled
-> const Preference
.PreferInstalled
865 PreferLatestForSelected
-> \pkgname
->
866 -- When you say cabal install foo, what you really mean is, prefer the
867 -- latest version of foo, but the installed version of everything else
868 if pkgname `Set
.member` selected
869 then Preference
.PreferLatest
870 else Preference
.PreferInstalled
872 stanzasPref
:: PackageName
-> [OptionalStanza
]
873 stanzasPref pkgname
=
874 fromMaybe [] (Map
.lookup pkgname stanzasPrefs
)
877 (\a b
-> nub (a
++ b
))
879 | PackageStanzasPreference pkgname pref
<- prefs
882 -- ------------------------------------------------------------
884 -- * Checking the result of the solver
886 -- ------------------------------------------------------------
888 -- | Make an install plan from the output of the dep resolver.
889 -- It checks that the plan is valid, or it's an error in the dep resolver.
894 -> [ResolverPackage UnresolvedPkgLoc
]
896 validateSolverResult platform comp indepGoals pkgs
=
897 case planPackagesProblems platform comp pkgs
of
898 [] -> case SolverInstallPlan
.new indepGoals graph
of
900 Left problems
-> error (formatPlanProblems problems
)
901 problems
-> error (formatPkgProblems problems
)
903 graph
:: Graph
.Graph
(ResolverPackage UnresolvedPkgLoc
)
904 graph
= Graph
.fromDistinctList pkgs
906 formatPkgProblems
:: [PlanPackageProblem
] -> String
907 formatPkgProblems
= formatProblemMessage
. map showPlanPackageProblem
908 formatPlanProblems
:: [SolverInstallPlan
.SolverPlanProblem
] -> String
909 formatPlanProblems
= formatProblemMessage
. map SolverInstallPlan
.showPlanProblem
911 formatProblemMessage problems
=
913 "internal error: could not construct a valid install plan."
914 : "The proposed (invalid) plan contained the following problems:"
917 : [SolverInstallPlan
.showPlanIndex pkgs
]
919 data PlanPackageProblem
920 = InvalidConfiguredPackage
921 (SolverPackage UnresolvedPkgLoc
)
923 | DuplicatePackageSolverId SolverId
[ResolverPackage UnresolvedPkgLoc
]
925 showPlanPackageProblem
:: PlanPackageProblem
-> String
926 showPlanPackageProblem
(InvalidConfiguredPackage pkg packageProblems
) =
928 ++ prettyShow
(packageId pkg
)
929 ++ " has an invalid configuration, in particular:\n"
931 [ " " ++ showPackageProblem problem
932 | problem
<- packageProblems
934 showPlanPackageProblem
(DuplicatePackageSolverId pid dups
) =
936 ++ prettyShow
(packageId pid
)
938 ++ show (length dups
)
939 ++ " duplicate instances."
944 -> [ResolverPackage UnresolvedPkgLoc
]
945 -> [PlanPackageProblem
]
946 planPackagesProblems platform cinfo pkgs
=
947 [ InvalidConfiguredPackage pkg packageProblems
948 | Configured pkg
<- pkgs
949 , let packageProblems
= configuredPackageProblems platform cinfo pkg
950 , not (null packageProblems
)
952 ++ [ DuplicatePackageSolverId
(Graph
.nodeKey aDup
) dups
953 | dups
<- duplicatesBy
(comparing Graph
.nodeKey
) pkgs
954 , aDup
<- case dups
of
960 = DuplicateFlag PD
.FlagName
961 | MissingFlag PD
.FlagName
962 | ExtraFlag PD
.FlagName
963 | DuplicateDeps
[PackageId
]
964 | MissingDep Dependency
966 | InvalidDep Dependency PackageId
968 showPackageProblem
:: PackageProblem
-> String
969 showPackageProblem
(DuplicateFlag flag
) =
970 "duplicate flag in the flag assignment: " ++ PD
.unFlagName flag
971 showPackageProblem
(MissingFlag flag
) =
972 "missing an assignment for the flag: " ++ PD
.unFlagName flag
973 showPackageProblem
(ExtraFlag flag
) =
974 "extra flag given that is not used by the package: " ++ PD
.unFlagName flag
975 showPackageProblem
(DuplicateDeps pkgids
) =
976 "duplicate packages specified as selected dependencies: "
977 ++ intercalate
", " (map prettyShow pkgids
)
978 showPackageProblem
(MissingDep dep
) =
979 "the package has a dependency "
981 ++ " but no package has been selected to satisfy it."
982 showPackageProblem
(ExtraDep pkgid
) =
983 "the package configuration specifies "
985 ++ " but (with the given flag assignment) the package does not actually"
986 ++ " depend on any version of that package."
987 showPackageProblem
(InvalidDep dep pkgid
) =
988 "the package depends on "
990 ++ " but the configuration specifies "
992 ++ " which does not satisfy the dependency."
994 -- | A 'ConfiguredPackage' is valid if the flag assignment is total and if
995 -- in the configuration given by the flag assignment, all the package
996 -- dependencies are satisfied by the specified packages.
997 configuredPackageProblems
1000 -> SolverPackage UnresolvedPkgLoc
1002 configuredPackageProblems
1005 (SolverPackage pkg specifiedFlags stanzas specifiedDeps0 _specifiedExeDeps
') =
1006 [ DuplicateFlag flag
1007 | flag
<- PD
.findDuplicateFlagAssignments specifiedFlags
1009 ++ [MissingFlag flag | OnlyInLeft flag
<- mergedFlags
]
1010 ++ [ExtraFlag flag | OnlyInRight flag
<- mergedFlags
]
1011 ++ [ DuplicateDeps pkgs
1015 (duplicatesBy
(comparing packageName
))
1019 ++ [MissingDep dep | OnlyInLeft dep
<- mergedDeps
]
1020 ++ [ExtraDep pkgid | OnlyInRight pkgid
<- mergedDeps
]
1021 ++ [ InvalidDep dep pkgid | InBoth dep pkgid
<- mergedDeps
, not (packageSatisfiesDependency pkgid dep
)
1024 -- TODO: sanity tests on executable deps
1026 thisPkgName
:: PackageName
1027 thisPkgName
= packageName
(srcpkgDescription pkg
)
1029 specifiedDeps1
:: ComponentDeps
[PackageId
]
1030 specifiedDeps1
= fmap (map solverSrcId
) specifiedDeps0
1032 specifiedDeps
:: [PackageId
]
1033 specifiedDeps
= CD
.flatDeps specifiedDeps1
1035 mergedFlags
:: [MergeResult PD
.FlagName PD
.FlagName
]
1039 (sort $ map PD
.flagName
(PD
.genPackageFlags
(srcpkgDescription pkg
)))
1040 (sort $ map fst (PD
.unFlagAssignment specifiedFlags
)) -- TODO
1041 packageSatisfiesDependency
:: PackageIdentifier
-> Dependency
-> Bool
1042 packageSatisfiesDependency
1043 (PackageIdentifier name version
)
1044 (Dependency name
' versionRange _
) =
1045 assert
(name
== name
') $
1046 version `withinRange` versionRange
1048 dependencyName
(Dependency name _ _
) = name
1050 mergedDeps
:: [MergeResult Dependency PackageId
]
1051 mergedDeps
= mergeDeps requiredDeps specifiedDeps
1056 -> [MergeResult Dependency PackageId
]
1057 mergeDeps required specified
=
1058 let sortNubOn f
= nubBy ((==) `on` f
) . sortBy (compare `on` f
)
1060 (\dep pkgid
-> dependencyName dep `
compare` packageName pkgid
)
1061 (sortNubOn dependencyName required
)
1062 (sortNubOn packageName specified
)
1064 compSpec
= enableStanzas stanzas
1065 -- TODO: It would be nicer to use ComponentDeps here so we can be more
1066 -- precise in our checks. In fact, this no longer relies on buildDepends and
1067 -- thus should be easier to fix. As long as we _do_ use a flat list here, we
1068 -- have to allow for duplicates when we fold specifiedDeps; once we have
1069 -- proper ComponentDeps here we should get rid of the `nubOn` in
1071 requiredDeps
:: [Dependency
]
1073 -- TODO: use something lower level than finalizePD
1081 (srcpkgDescription pkg
) of
1082 Right
(resolvedPkg
, _
) ->
1083 -- we filter self/internal dependencies. They are still there.
1084 -- This is INCORRECT.
1086 -- If we had per-component solver, it would make this unnecessary,
1087 -- but no finalizePDs picks components we are not building, eg. exes.
1091 ((/= thisPkgName
) . dependencyName
)
1092 (PD
.enabledBuildDepends resolvedPkg compSpec
)
1093 ++ maybe [] PD
.setupDepends
(PD
.setupBuildInfo resolvedPkg
)
1095 error "configuredPackageInvalidDeps internal error"
1097 -- ------------------------------------------------------------
1099 -- * Simple resolver that ignores dependencies
1101 -- ------------------------------------------------------------
1103 -- | A simplistic method of resolving a list of target package names to
1104 -- available packages.
1106 -- Specifically, it does not consider package dependencies at all. Unlike
1107 -- 'resolveDependencies', no attempt is made to ensure that the selected
1108 -- packages have dependencies that are satisfiable or consistent with
1111 -- It is suitable for tasks such as selecting packages to download for user
1112 -- inspection. It is not suitable for selecting packages to install.
1114 -- Note: if no installed package index is available, it is OK to pass 'mempty'.
1115 -- It simply means preferences for installed packages will be ignored.
1116 resolveWithoutDependencies
1117 :: DepResolverParams
1118 -> Either [ResolveNoDepsError
] [UnresolvedSourcePackage
]
1119 resolveWithoutDependencies
1130 _minimizeConflictSet
1138 _allowBootLibInstalls
1143 collectEithers
$ map selectPackage
(Set
.toList targets
)
1145 selectPackage
:: PackageName
-> Either ResolveNoDepsError UnresolvedSourcePackage
1146 selectPackage pkgname
1147 |
null choices
= Left
$! ResolveUnsatisfiable pkgname requiredVersions
1148 |
otherwise = Right
$! maximumBy bestByPrefs choices
1151 requiredVersions
:: VersionRange
1152 requiredVersions
= packageConstraints pkgname
1153 choices
:: [UnresolvedSourcePackage
]
1155 PackageIndex
.lookupDependency
1161 PackagePreferences preferredVersions preferInstalled _
=
1162 packagePreferences pkgname
1164 bestByPrefs
:: UnresolvedSourcePackage
-> UnresolvedSourcePackage
-> Ordering
1165 bestByPrefs
= comparing
$ \pkg
->
1166 (installPref pkg
, versionPref pkg
, packageVersion pkg
)
1167 installPref
:: UnresolvedSourcePackage
-> Bool
1168 installPref
= case preferInstalled
of
1169 Preference
.PreferLatest
-> const False
1170 Preference
.PreferOldest
-> const False
1171 Preference
.PreferInstalled
->
1174 . InstalledPackageIndex
.lookupSourcePackageId
1177 versionPref
:: Package a
=> a
-> Int
1179 length . filter (packageVersion pkg `withinRange`
) $
1182 packageConstraints
:: PackageName
-> VersionRange
1183 packageConstraints pkgname
=
1184 Map
.findWithDefault anyVersion pkgname packageVersionConstraintMap
1185 packageVersionConstraintMap
:: Map PackageName VersionRange
1186 packageVersionConstraintMap
=
1187 let pcs
= map unlabelPackageConstraint constraints
1189 [ (scopeToPackageName scope
, range)
1192 (PackagePropertyVersion
range) <-
1196 packagePreferences
:: PackageName
-> PackagePreferences
1197 packagePreferences
= interpretPackagesPreference targets defpref prefs
1199 collectEithers
:: [Either a b
] -> Either [a
] [b
]
1200 collectEithers
= collect
. partitionEithers
1202 collect
([], xs
) = Right xs
1203 collect
(errs
, _
) = Left errs
1205 -- | Errors for 'resolveWithoutDependencies'.
1206 data ResolveNoDepsError
1207 = -- | A package name which cannot be resolved to a specific package.
1208 -- Also gives the constraint on the version and whether there was
1209 -- a constraint on the package being installed.
1210 ResolveUnsatisfiable PackageName VersionRange
1212 instance Show ResolveNoDepsError
where
1213 show (ResolveUnsatisfiable name ver
) =
1214 "There is no available version of "
1216 ++ " that satisfies "
1217 ++ prettyShow
(simplifyVersionRange ver
)