summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Luther <SebastianLuther@gmx.de>2011-09-18 21:30:46 +0200
committerZac Medico <zmedico@gentoo.org>2011-09-18 13:02:19 -0700
commit57cc4e3e8991e7c4394d1dff7698aa62ed2a286b (patch)
tree990e0822af0ade81ffc7b873182ac7dbdf2d0d98
parent552720b56d811875b25cad201cd38641ad62da81 (diff)
downloadportage-57cc4e3e8991e7c4394d1dff7698aa62ed2a286b.tar.gz
portage-57cc4e3e8991e7c4394d1dff7698aa62ed2a286b.tar.bz2
portage-57cc4e3e8991e7c4394d1dff7698aa62ed2a286b.zip
autounmask: Ensure a suitable parent is displayed in the dep chain
Fixes bug 375265.
-rw-r--r--pym/_emerge/depgraph.py34
-rw-r--r--pym/portage/tests/resolver/test_autounmask.py64
2 files changed, 97 insertions, 1 deletions
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()