From: Zac Medico Date: Sun, 13 Feb 2011 10:20:24 +0000 (-0800) Subject: depgraph: fix and test --deep control of depth X-Git-Tag: v2.2.0_alpha24~23 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=5655b4dcfe5e9dae5e9d6352d791c3d04953baf7;p=portage.git depgraph: fix and test --deep control of depth Control over recursion depth hasn't behaved properly since commit 6503980e0e3bcfce9fbaff85c33d87f616e955a9. Now it is fixed and tested. --- diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index bec9ffd1b..72fc1ae59 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -18,7 +18,7 @@ from portage.const import PORTAGE_PACKAGE_ATOM from portage.dbapi import dbapi from portage.dep import Atom, 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 +from portage.exception import InvalidAtom, InvalidDependString from portage.output import colorize, create_color_func, \ darkgreen, green bad = create_color_func("BAD") @@ -1206,6 +1206,8 @@ class depgraph(object): def _add_pkg_dep_string(self, pkg, dep_root, dep_priority, dep_string, allow_unsatisfied, ignore_blockers=False): depth = pkg.depth + 1 + deep = self._dynamic_config.myparams.get("deep", 0) + recurse_satisfied = deep is True or depth <= deep debug = "--debug" in self._frozen_config.myopts strict = pkg.type_name != "installed" @@ -1244,6 +1246,7 @@ class depgraph(object): # from dep_check, map it back to the original, in # order to avoid distortion in places like display # or conflict resolution code. + is_virt = hasattr(atom, '_orig_atom') atom = getattr(atom, '_orig_atom', atom) if ignore_blockers and atom.blocker: @@ -1264,9 +1267,44 @@ class depgraph(object): # none visible, so use highest mypriority.satisfied = inst_pkgs[0] - if not self._add_dep(Dependency(atom=atom, + dep = Dependency(atom=atom, blocker=atom.blocker, child=child, depth=depth, parent=pkg, - priority=mypriority, root=dep_root), + priority=mypriority, root=dep_root) + + # In some cases, dep_check will return deps that shouldn't + # be proccessed any further, so they are identified and + # discarded here. Try to discard as few as possible since + # discarded dependencies reduce the amount of information + # available for optimization of merge order. + ignored = False + if not atom.blocker and \ + not is_virt and \ + not recurse_satisfied and \ + mypriority.satisfied and \ + mypriority.satisfied.visible and \ + dep.child is not None and \ + not dep.child.installed: + myarg = None + if dep.root == self._frozen_config.target_root: + try: + myarg = next(self._iter_atoms_for_pkg(dep.child)) + except StopIteration: + pass + except InvalidDependString: + if not dep.child.installed: + # This shouldn't happen since the package + # should have been masked. + raise + + if myarg is None: + # Existing child selection may not be valid unless + # it's added to the graph immediately, since "complete" + # mode may select a different child later. + ignored = True + dep.child = None + self._dynamic_config._ignored_deps.append(dep) + + if not ignored and not self._add_dep(dep, allow_unsatisfied=allow_unsatisfied): return 0 diff --git a/pym/portage/tests/resolver/test_depth.py b/pym/portage/tests/resolver/test_depth.py new file mode 100644 index 000000000..5a309416d --- /dev/null +++ b/pym/portage/tests/resolver/test_depth.py @@ -0,0 +1,53 @@ +# Copyright 2011 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +from portage.tests import TestCase +from portage.tests.resolver.ResolverPlayground import (ResolverPlayground, + ResolverPlaygroundTestCase) + +class ResolverDepthTestCase(TestCase): + + def testResolverDepth(self): + + ebuilds = { + "dev-libs/A-1": {"RDEPEND" : "dev-libs/B"}, + "dev-libs/A-2": {"RDEPEND" : "dev-libs/B"}, + "dev-libs/B-1": {"RDEPEND" : "dev-libs/C"}, + "dev-libs/B-2": {"RDEPEND" : "dev-libs/C"}, + "dev-libs/C-1": {}, + "dev-libs/C-2": {}, + } + + installed = { + "dev-libs/A-1": {"RDEPEND" : "dev-libs/B"}, + "dev-libs/B-1": {"RDEPEND" : "dev-libs/C"}, + "dev-libs/C-1": {}, + } + + test_cases = ( + ResolverPlaygroundTestCase( + ["dev-libs/A"], + options = {"--update": True, "--deep": 0}, + success = True, + mergelist = ["dev-libs/A-2"]), + + ResolverPlaygroundTestCase( + ["dev-libs/A"], + options = {"--update": True, "--deep": 1}, + success = True, + mergelist = ["dev-libs/B-2", "dev-libs/A-2"]), + + ResolverPlaygroundTestCase( + ["dev-libs/A"], + options = {"--update": True, "--deep": 3}, + success = True, + mergelist = ["dev-libs/C-2", "dev-libs/B-2", "dev-libs/A-2"]), + ) + + playground = ResolverPlayground(ebuilds=ebuilds, installed=installed) + 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()