diff options
author | kitsunyan | 2018-03-13 01:49:38 +0000 |
---|---|---|
committer | kitsunyan | 2018-03-13 01:49:38 +0000 |
commit | 9a2357c70b7a704877515c0a4418a85a5ccecfcd (patch) | |
tree | 51d5ffe7e7e317afe6035207969f01fd0eed49b6 | |
parent | 3b984b6b8f6107ec37c35cf4091e1a85a0a22abb (diff) |
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.
-rw-r--r-- | src/feature/syncinstall.nim | 14 |
1 files changed, 13 insertions, 1 deletions
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) |