From 92d9c95c83ddc6ac7b59395db92c0c8d81d7687a Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Sat, 6 Jul 2013 14:45:04 -0700 Subject: [PATCH] depgraph: tweak slot-operator merge order This handles circular DEPEND/RDEPEND with one := operator, so that when both deps are already satisfied by installed packages, the := dep is given higher priority in merge order. --- pym/_emerge/AbstractDepPriority.py | 5 +-- pym/_emerge/DepPriority.py | 29 +++++++++------ pym/_emerge/DepPrioritySatisfiedRange.py | 23 ++++++++---- pym/_emerge/UnmergeDepPriority.py | 25 +++++++------ pym/_emerge/depgraph.py | 7 ++++ .../tests/resolver/test_merge_order.py | 35 ++++++++++++++++++- 6 files changed, 93 insertions(+), 31 deletions(-) diff --git a/pym/_emerge/AbstractDepPriority.py b/pym/_emerge/AbstractDepPriority.py index 94f26efc5..1fcd04345 100644 --- a/pym/_emerge/AbstractDepPriority.py +++ b/pym/_emerge/AbstractDepPriority.py @@ -1,11 +1,12 @@ -# Copyright 1999-2012 Gentoo Foundation +# Copyright 1999-2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import copy from portage.util.SlotObject import SlotObject class AbstractDepPriority(SlotObject): - __slots__ = ("buildtime", "runtime", "runtime_post") + __slots__ = ("buildtime", "buildtime_slot_op", + "runtime", "runtime_post", "runtime_slot_op") def __lt__(self, other): return self.__int__() < other diff --git a/pym/_emerge/DepPriority.py b/pym/_emerge/DepPriority.py index 3c2256a8e..34fdb481c 100644 --- a/pym/_emerge/DepPriority.py +++ b/pym/_emerge/DepPriority.py @@ -1,4 +1,4 @@ -# Copyright 1999-2011 Gentoo Foundation +# Copyright 1999-2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 from _emerge.AbstractDepPriority import AbstractDepPriority @@ -16,31 +16,38 @@ class DepPriority(AbstractDepPriority): Attributes Hardness - buildtime 0 - runtime -1 - runtime_post -2 - optional -3 - (none of the above) -4 + buildtime_slot_op 0 + buildtime -1 + runtime -2 + runtime_post -3 + optional -4 + (none of the above) -5 """ if self.optional: - return -3 - if self.buildtime: + return -4 + if self.buildtime_slot_op: return 0 - if self.runtime: + if self.buildtime: return -1 - if self.runtime_post: + if self.runtime: return -2 - return -4 + if self.runtime_post: + return -3 + return -5 def __str__(self): if self.ignored: return "ignored" if self.optional: return "optional" + if self.buildtime_slot_op: + return "buildtime_slot_op" if self.buildtime: return "buildtime" + if self.runtime_slot_op: + return "runtime_slot_op" if self.runtime: return "runtime" if self.runtime_post: diff --git a/pym/_emerge/DepPrioritySatisfiedRange.py b/pym/_emerge/DepPrioritySatisfiedRange.py index edb29df96..e5fdba9f1 100644 --- a/pym/_emerge/DepPrioritySatisfiedRange.py +++ b/pym/_emerge/DepPrioritySatisfiedRange.py @@ -1,4 +1,4 @@ -# Copyright 1999-2011 Gentoo Foundation +# Copyright 1999-2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 from _emerge.DepPriority import DepPriority @@ -7,17 +7,18 @@ class DepPrioritySatisfiedRange(object): DepPriority Index Category not satisfied and buildtime HARD - not satisfied and runtime 6 MEDIUM - not satisfied and runtime_post 5 MEDIUM_SOFT + not satisfied and runtime 7 MEDIUM + not satisfied and runtime_post 6 MEDIUM_SOFT + satisfied and buildtime_slot_op 5 SOFT satisfied and buildtime 4 SOFT satisfied and runtime 3 SOFT satisfied and runtime_post 2 SOFT optional 1 SOFT (none of the above) 0 NONE """ - MEDIUM = 6 - MEDIUM_SOFT = 5 - SOFT = 4 + MEDIUM = 7 + MEDIUM_SOFT = 6 + SOFT = 5 NONE = 0 @classmethod @@ -48,6 +49,15 @@ class DepPrioritySatisfiedRange(object): @classmethod def _ignore_satisfied_buildtime(cls, priority): + if priority.__class__ is not DepPriority: + return False + if priority.buildtime_slot_op: + return False + return bool(priority.optional or \ + priority.satisfied) + + @classmethod + def _ignore_satisfied_buildtime_slot_op(cls, priority): if priority.__class__ is not DepPriority: return False return bool(priority.optional or \ @@ -80,6 +90,7 @@ DepPrioritySatisfiedRange.ignore_priority = ( DepPrioritySatisfiedRange._ignore_satisfied_runtime_post, DepPrioritySatisfiedRange._ignore_satisfied_runtime, DepPrioritySatisfiedRange._ignore_satisfied_buildtime, + DepPrioritySatisfiedRange._ignore_satisfied_buildtime_slot_op, DepPrioritySatisfiedRange._ignore_runtime_post, DepPrioritySatisfiedRange._ignore_runtime ) diff --git a/pym/_emerge/UnmergeDepPriority.py b/pym/_emerge/UnmergeDepPriority.py index 43166006f..0457ea904 100644 --- a/pym/_emerge/UnmergeDepPriority.py +++ b/pym/_emerge/UnmergeDepPriority.py @@ -1,4 +1,4 @@ -# Copyright 1999-2011 Gentoo Foundation +# Copyright 1999-2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 from _emerge.AbstractDepPriority import AbstractDepPriority @@ -7,15 +7,16 @@ class UnmergeDepPriority(AbstractDepPriority): """ Combination of properties Priority Category - runtime 0 HARD - runtime_post -1 HARD - buildtime -2 SOFT - (none of the above) -2 SOFT + runtime_slot_op 0 HARD + runtime -1 HARD + runtime_post -2 HARD + buildtime -3 SOFT + (none of the above) -3 SOFT """ MAX = 0 - SOFT = -2 - MIN = -2 + SOFT = -3 + MIN = -3 def __init__(self, **kwargs): AbstractDepPriority.__init__(self, **kwargs) @@ -23,13 +24,15 @@ class UnmergeDepPriority(AbstractDepPriority): self.optional = True def __int__(self): - if self.runtime: + if self.runtime_slot_op: return 0 - if self.runtime_post: + if self.runtime: return -1 - if self.buildtime: + if self.runtime_post: return -2 - return -2 + if self.buildtime: + return -3 + return -3 def __str__(self): if self.ignored: diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index b2d79a808..939adde49 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -2254,6 +2254,13 @@ class depgraph(object): mypriority = dep_priority.copy() if not atom.blocker: + + if atom.slot_operator == "=": + if mypriority.buildtime: + mypriority.buildtime_slot_op = True + if mypriority.runtime: + mypriority.runtime_slot_op = True + inst_pkgs = [inst_pkg for inst_pkg in reversed(vardb.match_pkgs(atom)) if not reinstall_atoms.findAtomForPackage(inst_pkg, diff --git a/pym/portage/tests/resolver/test_merge_order.py b/pym/portage/tests/resolver/test_merge_order.py index 5b5709afe..5d000d12b 100644 --- a/pym/portage/tests/resolver/test_merge_order.py +++ b/pym/portage/tests/resolver/test_merge_order.py @@ -1,4 +1,4 @@ -# Copyright 2011 Gentoo Foundation +# Copyright 2011-2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import portage @@ -191,6 +191,12 @@ class MergeOrderTestCase(TestCase): "DEPEND" : "kde-base/libkdegames", "RDEPEND" : "kde-base/libkdegames", }, + "media-libs/mesa-9.1.3" : { + "EAPI" : "5", + "IUSE" : "+xorg", + "DEPEND" : "xorg? ( x11-base/xorg-server:= )", + "RDEPEND" : "xorg? ( x11-base/xorg-server:= )", + }, "media-video/libav-0.7_pre20110327" : { "EAPI" : "2", "IUSE" : "X +encode", @@ -205,6 +211,12 @@ class MergeOrderTestCase(TestCase): "IUSE" : "X +encode", "RDEPEND" : "|| ( >=media-video/ffmpeg-0.6.90_rc0-r2[X=,encode=] >=media-video/libav-0.6.90_rc[X=,encode=] )", }, + "x11-base/xorg-server-1.14.1" : { + "EAPI" : "5", + "SLOT": "0/1.14.1", + "DEPEND" : "media-libs/mesa", + "RDEPEND" : "media-libs/mesa", + }, } installed = { @@ -256,6 +268,13 @@ class MergeOrderTestCase(TestCase): "RDEPEND": "", }, "app-arch/xz-utils-5.0.1" : {}, + "media-libs/mesa-9.1.3" : { + "EAPI" : "5", + "IUSE" : "+xorg", + "USE": "xorg", + "DEPEND" : "x11-base/xorg-server:0/1.14.1=", + "RDEPEND" : "x11-base/xorg-server:0/1.14.1=", + }, "media-video/ffmpeg-0.7_rc1" : { "EAPI" : "2", "IUSE" : "X +encode", @@ -267,6 +286,12 @@ class MergeOrderTestCase(TestCase): "USE" : "encode", "RDEPEND" : "|| ( >=media-video/ffmpeg-0.6.90_rc0-r2[X=,encode=] >=media-video/libav-0.6.90_rc[X=,encode=] )", }, + "x11-base/xorg-server-1.14.1" : { + "EAPI" : "5", + "SLOT": "0/1.14.1", + "DEPEND" : "media-libs/mesa", + "RDEPEND" : "media-libs/mesa", + }, } test_cases = ( @@ -434,6 +459,14 @@ class MergeOrderTestCase(TestCase): ('kde-base/libkdegames-3.5.7', 'kde-base/kmines-3.5.7'), ), mergelist = [('kde-base/kdelibs-3.5.7', 'dev-util/pkgconfig-0.25-r2', 'kde-misc/kdnssd-avahi-0.1.2', 'app-arch/xz-utils-5.0.2', 'kde-base/libkdegames-3.5.7', 'kde-base/kdnssd-3.5.7', 'kde-base/kmines-3.5.7')]), + # Test satisfied circular DEPEND/RDEPEND with one := operator. + # Both deps are already satisfied by installed packages, but + # the := dep is given higher priority in merge order. + ResolverPlaygroundTestCase( + ["media-libs/mesa", "x11-base/xorg-server"], + success=True, + all_permutations = True, + mergelist = ['x11-base/xorg-server-1.14.1', 'media-libs/mesa-9.1.3']), ) playground = ResolverPlayground(ebuilds=ebuilds, installed=installed) -- 2.26.2