From 57cc4e3e8991e7c4394d1dff7698aa62ed2a286b Mon Sep 17 00:00:00 2001 From: Sebastian Luther Date: Sun, 18 Sep 2011 21:30:46 +0200 Subject: autounmask: Ensure a suitable parent is displayed in the dep chain Fixes bug 375265. --- pym/_emerge/depgraph.py | 34 +++++++++++++- pym/portage/tests/resolver/test_autounmask.py | 64 +++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index fbbae1e29..400207e4e 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -18,7 +18,8 @@ from portage import os, OrderedDict from portage import _unicode_decode, _unicode_encode, _encodings from portage.const import PORTAGE_PACKAGE_ATOM, USER_CONFIG_PATH from portage.dbapi import dbapi -from portage.dep import Atom, extract_affecting_use, check_required_use, human_readable_required_use, _repo_separator +from portage.dep import Atom, best_match_to_list, extract_affecting_use, \ + check_required_use, human_readable_required_use, _repo_separator from portage.eapi import eapi_has_strong_blocks, eapi_has_required_use from portage.exception import InvalidAtom, InvalidDependString, PortageException from portage.output import colorize, create_color_func, \ @@ -2694,6 +2695,37 @@ class depgraph(object): dep_chain.append((pkg_name, node.type_name)) + + # To build a dep chain for the given package we take + # "random" parents form the digraph, except for the + # first package, because we want a parent that forced + # the corresponding change (i.e '>=foo-2', instead 'foo'). + + traversed_nodes.add(start_node) + + start_node_parent_atoms = {} + for ppkg, patom in all_parents[node]: + # Get a list of suitable atoms. For use deps + # (aka unsatisfied_dependency is not None) we + # need that the start_node doesn't match the atom. + if not unsatisfied_dependency or \ + not InternalPackageSet(initial_atoms=(patom,)).findAtomForPackage(start_node): + start_node_parent_atoms.setdefault(patom, []).append(ppkg) + + if start_node_parent_atoms: + # If there are parents in all_parents then use one of them. + # If not, then this package got pulled in by an Arg and + # will be correctly handled by the code that handles later + # packages in the dep chain. + best_match = best_match_to_list(node.cpv, start_node_parent_atoms) + + child = node + for ppkg in start_node_parent_atoms[best_match]: + node = ppkg + if ppkg in self._dynamic_config._initial_arg_list: + # Stop if reached the top level of the dep chain. + break + while node is not None: traversed_nodes.add(node) diff --git a/pym/portage/tests/resolver/test_autounmask.py b/pym/portage/tests/resolver/test_autounmask.py index 54c435f56..ff13789dc 100644 --- a/pym/portage/tests/resolver/test_autounmask.py +++ b/pym/portage/tests/resolver/test_autounmask.py @@ -1,6 +1,7 @@ # Copyright 2010-2011 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 +from portage.const import _ENABLE_SET_CONFIG from portage.tests import TestCase from portage.tests.resolver.ResolverPlayground import ResolverPlayground, ResolverPlaygroundTestCase @@ -324,3 +325,66 @@ class AutounmaskTestCase(TestCase): self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.cleanup() + + + def testAutounmaskAndSets(self): + + if not _ENABLE_SET_CONFIG: + return + + ebuilds = { + #ebuilds to test use changes + "dev-libs/A-1": { }, + "dev-libs/A-2": { "KEYWORDS": "~x86" }, + "dev-libs/B-1": { "DEPEND": "dev-libs/A" }, + "dev-libs/C-1": { "DEPEND": ">=dev-libs/A-2" }, + "dev-libs/D-1": { "DEPEND": "dev-libs/A" }, + } + + world_sets = [ "@test-set" ] + sets = { + "test-set": ( + "dev-libs/A", "dev-libs/B", "dev-libs/C", "dev-libs/D", + ), + } + + test_cases = ( + #Test USE changes. + #The simple case. + + ResolverPlaygroundTestCase( + ["dev-libs/B", "dev-libs/C", "dev-libs/D"], + all_permutations=True, + options = {"--autounmask": "y"}, + mergelist=["dev-libs/A-2", "dev-libs/B-1", "dev-libs/C-1", "dev-libs/D-1"], + ignore_mergelist_order=True, + unstable_keywords = ["dev-libs/A-2"], + success = False), + + ResolverPlaygroundTestCase( + ["@test-set"], + all_permutations=True, + options = {"--autounmask": "y"}, + mergelist=["dev-libs/A-2", "dev-libs/B-1", "dev-libs/C-1", "dev-libs/D-1"], + ignore_mergelist_order=True, + unstable_keywords = ["dev-libs/A-2"], + success = False), + + ResolverPlaygroundTestCase( + ["@world"], + all_permutations=True, + options = {"--autounmask": "y"}, + mergelist=["dev-libs/A-2", "dev-libs/B-1", "dev-libs/C-1", "dev-libs/D-1"], + ignore_mergelist_order=True, + unstable_keywords = ["dev-libs/A-2"], + success = False), + ) + + + playground = ResolverPlayground(ebuilds=ebuilds, world_sets=world_sets, sets=sets) + 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() -- cgit v1.2.3-1-g7c22