From c42591b5d0484459837da28482f70fad9ff13824 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Tue, 10 Jul 2012 15:45:12 -0700 Subject: [PATCH] emerge: add --complete-graph-if-new-use < y | n > Trigger the --complete-graph behavior if USE or IUSE will change for an installed package. This option is enabled by default. This will fix bug #425558. --- man/emerge.1 | 4 ++ pym/_emerge/create_depgraph_params.py | 5 ++ pym/_emerge/depgraph.py | 26 ++++++-- pym/_emerge/main.py | 6 ++ .../tests/resolver/test_complete_graph.py | 66 ++++++++++++++++++- 5 files changed, 101 insertions(+), 6 deletions(-) diff --git a/man/emerge.1 b/man/emerge.1 index b45e41b5a..7aa46226c 100644 --- a/man/emerge.1 +++ b/man/emerge.1 @@ -396,6 +396,10 @@ be updated than would have otherwise been updated with the option disabled. Using \fB\-\-with\-bdeps=y\fR together with \fB\-\-complete\-graph\fR makes the graph as complete as possible. .TP +.BR "\-\-complete\-graph\-if\-new\-use < y | n >" +Trigger the \fB\-\-complete\-graph\fR behavior if USE or IUSE will +change for an installed package. This option is enabled by default. +.TP .BR "\-\-complete\-graph\-if\-new\-ver < y | n >" Trigger the \fB\-\-complete\-graph\fR behavior if an installed package version will change (upgrade or downgrade). This option is enabled by default. diff --git a/pym/_emerge/create_depgraph_params.py b/pym/_emerge/create_depgraph_params.py index 33d413aa3..2838e93c3 100644 --- a/pym/_emerge/create_depgraph_params.py +++ b/pym/_emerge/create_depgraph_params.py @@ -56,6 +56,11 @@ def create_depgraph_params(myopts, myaction): if deep is not None and deep != 0: myparams["deep"] = deep + complete_if_new_use = \ + myopts.get("--complete-graph-if-new-use") + if complete_if_new_use is not None: + myparams["complete_if_new_use"] = complete_if_new_use + complete_if_new_ver = \ myopts.get("--complete-graph-if-new-ver") if complete_if_new_ver is not None: diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index f819aef3d..703720cf0 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -4643,6 +4643,8 @@ class depgraph(object): "recurse" not in self._dynamic_config.myparams: return 1 + complete_if_new_use = self._dynamic_config.myparams.get( + "complete_if_new_use", "y") == "y" complete_if_new_ver = self._dynamic_config.myparams.get( "complete_if_new_ver", "y") == "y" rebuild_if_new_slot_abi = self._dynamic_config.myparams.get( @@ -4650,8 +4652,10 @@ class depgraph(object): complete_if_new_slot = rebuild_if_new_slot_abi if "complete" not in self._dynamic_config.myparams and \ - (complete_if_new_ver or complete_if_new_slot): - # Enable complete mode if an installed package version will change. + (complete_if_new_use or + complete_if_new_ver or complete_if_new_slot): + # Enable complete mode if an installed package will change somehow. + use_change = False version_change = False for node in self._dynamic_config.digraph: if not isinstance(node, Package) or \ @@ -4660,14 +4664,26 @@ class depgraph(object): vardb = self._frozen_config.roots[ node.root].trees["vartree"].dbapi - if complete_if_new_ver: + if complete_if_new_use or complete_if_new_ver: inst_pkg = vardb.match_pkgs(node.slot_atom) if inst_pkg and inst_pkg[0].cp == node.cp: inst_pkg = inst_pkg[0] - if inst_pkg < node or node < inst_pkg: + if complete_if_new_ver and \ + (inst_pkg < node or node < inst_pkg): version_change = True break + # Intersect enabled USE with IUSE, in order to + # ignore forced USE from implicit IUSE flags, since + # they're probably irrelevant and they are sensitive + # to use.mask/force changes in the profile. + if complete_if_new_use and \ + (node.iuse.all != inst_pkg.iuse.all or + node.use.enabled.intersection(node.iuse.all) != + inst_pkg.use.enabled.intersection(inst_pkg.iuse.all)): + use_change = True + break + if complete_if_new_slot: cp_list = vardb.match_pkgs(Atom(node.cp)) if (cp_list and cp_list[0].cp == node.cp and @@ -4675,7 +4691,7 @@ class depgraph(object): version_change = True break - if version_change: + if use_change or version_change: self._dynamic_config.myparams["complete"] = True if "complete" not in self._dynamic_config.myparams: diff --git a/pym/_emerge/main.py b/pym/_emerge/main.py index 2a0e67f1d..640f320fd 100644 --- a/pym/_emerge/main.py +++ b/pym/_emerge/main.py @@ -703,6 +703,12 @@ def parse_opts(tmpcmdline, silent=False): "choices" : true_y_or_n }, + "--complete-graph-if-new-use": { + "help" : "trigger --complete-graph behavior if USE or IUSE will change for an installed package", + "type" : "choice", + "choices" : y_or_n + }, + "--complete-graph-if-new-ver": { "help" : "trigger --complete-graph behavior if an installed package version will change (upgrade or downgrade)", "type" : "choice", diff --git a/pym/portage/tests/resolver/test_complete_graph.py b/pym/portage/tests/resolver/test_complete_graph.py index 850b883b4..1b0342c67 100644 --- a/pym/portage/tests/resolver/test_complete_graph.py +++ b/pym/portage/tests/resolver/test_complete_graph.py @@ -1,4 +1,4 @@ -# Copyright 2011 Gentoo Foundation +# Copyright 2011-2012 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 from portage.tests import TestCase @@ -7,6 +7,70 @@ from portage.tests.resolver.ResolverPlayground import (ResolverPlayground, class CompleteGraphTestCase(TestCase): + def testCompleteGraphUseChange(self): + """ + Prevent reverse dependency breakage triggered by USE changes. + """ + + ebuilds = { + "dev-libs/libxml2-2.8.0": { + "EAPI": "2", + "IUSE": "+icu", + "SLOT": "2", + }, + "x11-libs/qt-webkit-4.8.2": { + "EAPI": "2", + "IUSE": "icu", + "RDEPEND" : "dev-libs/libxml2:2[!icu?]", + }, + } + + installed = { + "dev-libs/libxml2-2.8.0": { + "EAPI": "2", + "IUSE": "+icu", + "USE": "", + "SLOT": "2", + }, + "x11-libs/qt-webkit-4.8.2": { + "EAPI": "2", + "IUSE": "icu", + "RDEPEND" : "dev-libs/libxml2:2[-icu]", + "USE": "", + } + } + + world = ["x11-libs/qt-webkit"] + + test_cases = ( + + ResolverPlaygroundTestCase( + ["dev-libs/libxml2"], + options = {"--complete-graph-if-new-use" : "y" }, + mergelist = ["dev-libs/libxml2-2.8.0"], + slot_collision_solutions = [{'dev-libs/libxml2-2.8.0': {'icu': False}}], + success = False, + ), + + ResolverPlaygroundTestCase( + ["dev-libs/libxml2"], + options = {"--complete-graph-if-new-use" : "n" }, + mergelist = ["dev-libs/libxml2-2.8.0"], + success = True, + ), + + ) + + playground = ResolverPlayground(ebuilds=ebuilds, + installed=installed, world=world, debug=False) + + try: + for test_case in test_cases: + playground.run_TestCase(test_case) + self.assertEqual(test_case.test_success, True, test_case.fail_msg) + finally: + playground.cleanup() + def testCompleteGraphVersionChange(self): """ Prevent reverse dependency breakage triggered by version changes. -- 2.26.2