From 9a2357c70b7a704877515c0a4418a85a5ccecfcd Mon Sep 17 00:00:00 2001 From: kitsunyan Date: Tue, 13 Mar 2018 04:49:38 +0300 Subject: Fix dependency resolver for dependency cycles X provides Y, X depends on Z, Z depends on Y (X and Y — actual packages). Before this commit, resolver wouldn't lookup for Y since it's already provided by X. --- src/feature/syncinstall.nim | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src/feature/syncinstall.nim') diff --git a/src/feature/syncinstall.nim b/src/feature/syncinstall.nim index 5f6e082..06ea1d2 100644 --- a/src/feature/syncinstall.nim +++ b/src/feature/syncinstall.nim @@ -67,6 +67,17 @@ proc orderInstallation(pkgInfos: seq[PackageInfo], proc findDependencies(config: Config, handle: ptr AlpmHandle, dbs: seq[ptr AlpmDatabase], satisfied: Table[PackageReference, SatisfyResult], unsatisfied: seq[PackageReference], printMode: bool, noaur: bool): (Table[PackageReference, SatisfyResult], seq[PackageReference]) = + proc checkDependencyCycle(pkgInfo: PackageInfo, reference: PackageReference): bool = + for checkReference in pkgInfo.allDepends: + if checkReference.arch.isNone or checkReference.arch == some(config.arch): + if checkReference.reference == reference: + return false + let buildPkgInfo = satisfied.opt(checkReference.reference) + .map(r => r.buildPkgInfo).flatten + if buildPkgInfo.isSome and not checkDependencyCycle(buildPkgInfo.unsafeGet, reference): + return false + return true + proc findInSatisfied(reference: PackageReference): Option[PackageInfo] = for satref, res in satisfied.pairs: if res.buildPkgInfo.isSome: @@ -76,7 +87,8 @@ proc findDependencies(config: Config, handle: ptr AlpmHandle, dbs: seq[ptr AlpmD return some(pkgInfo) for provides in pkgInfo.provides: if provides.arch.isNone or provides.arch == some(config.arch): - if reference.isProvidedBy(provides.reference): + if reference.isProvidedBy(provides.reference) and + checkDependencyCycle(pkgInfo, reference): return some(pkgInfo) return none(PackageInfo) -- cgit v1.2.3-70-g09d2