From: Sebastian Luther Date: Fri, 28 Jan 2011 12:59:41 +0000 (+0100) Subject: Show use conditionals in old style dep chains X-Git-Tag: v2.2.0_alpha20~89 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=5a9d387c25ff13500d5898cb58fdc2d3e6637204;p=portage.git Show use conditionals in old style dep chains --- diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index a4cdaf2e6..3444731ab 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -2175,6 +2175,117 @@ class depgraph(object): return selected_atoms + def _get_dep_chain(self, pkg, atom=None): + """ + Returns a list of (atom, node_type) pairs that represent a dep chain. + If atom is None, the first package shown is pkg's paretn. + If atom is not None the first package shown is pkg. + """ + traversed_nodes = set() + dep_chain = [] + node = pkg + first = True + child = None + all_parents = self._dynamic_config._parent_atoms + + if atom is not None: + affecting_use = set() + for dep_str in "DEPEND", "RDEPEND", "PDEPEND": + affecting_use.update(extract_affecting_use(pkg.metadata[dep_str], atom)) + affecting_use.difference_update(pkg.use.mask, node.use.force) + pkg_name = pkg.cpv + if affecting_use: + usedep = [] + for flag in affecting_use: + if flag in self._pkg_use_enabled(node): + usedep.append(flag) + else: + usedep.append("-"+flag) + pkg_name += "[%s]" % ",".join(usedep) + + + dep_chain.append(( _unicode_decode(pkg_name), _unicode_decode(pkg.type_name))) + + while node is not None: + traversed_nodes.add(node) + + if isinstance(node, DependencyArg): + dep_chain.append((_unicode_decode(node), "argument")) + + elif node is not pkg: + for ppkg, patom in all_parents[child]: + if ppkg == node: + atom = patom.unevaluated_atom + break + + dep_strings = set() + for priority in self._dynamic_config.digraph.nodes[node][0][child]: + if priority.buildtime: + dep_strings.add(node.metadata["DEPEND"]) + if priority.runtime: + dep_strings.add(node.metadata["RDEPEND"]) + if priority.runtime_post: + dep_strings.add(node.metadata["PDEPEND"]) + + affecting_use = set() + for dep_str in dep_strings: + affecting_use.update(extract_affecting_use(dep_str, atom)) + + #Don't show flags as 'affecting' if the user can't change them, + affecting_use.difference_update(node.use.mask, \ + node.use.force) + + pkg_name = node.cpv + if affecting_use: + usedep = [] + for flag in affecting_use: + if flag in self._pkg_use_enabled(node): + usedep.append(flag) + else: + usedep.append("-"+flag) + pkg_name += "[%s]" % ",".join(usedep) + + + dep_chain.append(( _unicode_decode(pkg_name), _unicode_decode(node.type_name))) + + if node not in self._dynamic_config.digraph: + # The parent is not in the graph due to backtracking. + break + + # When traversing to parents, prefer arguments over packages + # since arguments are root nodes. Never traverse the same + # package twice, in order to prevent an infinite loop. + selected_parent = None + for parent in self._dynamic_config.digraph.parent_nodes(node): + if parent in traversed_nodes: + continue + if isinstance(parent, DependencyArg): + if self._dynamic_config.digraph.parent_nodes(parent): + selected_parent = parent + child = node + else: + dep_chain.append(( _unicode_decode(parent), "argument")) + selected_parent = None + break + else: + selected_parent = parent + child = node + node = selected_parent + return dep_chain + + def _get_dep_chain_as_comment(self, pkg): + dep_chain = self._get_dep_chain(pkg) + display_list = [] + for node, node_type in dep_chain: + if node_type == "argument": + display_list.append("required by %s (argument)" % node) + else: + display_list.append("required by %s" % node) + + msg = "#" + ", ".join(display_list) + "\n" + return msg + + def _show_unsatisfied_dep(self, root, atom, myparent=None, arg=None, check_backtrack=False): """ @@ -2479,48 +2590,17 @@ class depgraph(object): else: writemsg_stdout("\nemerge: there are no ebuilds to satisfy "+green(xinfo)+".\n", noiselevel=-1) - # Show parent nodes and the argument that pulled them in. - traversed_nodes = set() - node = myparent - if isinstance(myparent, AtomArg): + msg = [] + if not isinstance(myparent, AtomArg): # It's redundant to show parent for AtomArg since # it's the same as 'xinfo' displayed above. - node = None - else: - node = myparent - msg = [] - while node is not None: - traversed_nodes.add(node) - if isinstance(node, DependencyArg): - msg.append('(dependency required by "%s")' % \ - colorize('INFORM', _unicode_decode("%s") % (node,))) - else: + dep_chain = self._get_dep_chain(myparent, atom) + + for node, node_type in dep_chain: msg.append('(dependency required by "%s" [%s])' % \ - (colorize('INFORM', _unicode_decode("%s") % \ - (node.cpv,)), node.type_name)) - - if node not in self._dynamic_config.digraph: - # The parent is not in the graph due to backtracking. - break + (colorize('INFORM', _unicode_decode("%s") % \ + (node)), node_type)) - # When traversing to parents, prefer arguments over packages - # since arguments are root nodes. Never traverse the same - # package twice, in order to prevent an infinite loop. - selected_parent = None - for parent in self._dynamic_config.digraph.parent_nodes(node): - if parent in traversed_nodes: - continue - if isinstance(parent, DependencyArg): - if self._dynamic_config.digraph.parent_nodes(parent): - selected_parent = parent - else: - msg.append('(dependency required by "%s" [argument])' % \ - colorize('INFORM', _unicode_decode("%s") % (parent,))) - selected_parent = None - break - else: - selected_parent = parent - node = selected_parent if msg: writemsg_stdout("\n".join(msg), noiselevel=-1) writemsg_stdout("\n", noiselevel=-1) @@ -4845,91 +4925,6 @@ class depgraph(object): else: self._show_missed_update() - def get_dep_chain(pkg): - traversed_nodes = set() - msg = "#" - node = pkg - first = True - child = None - all_parents = self._dynamic_config._parent_atoms - while node is not None: - traversed_nodes.add(node) - if isinstance(node, DependencyArg): - if first: - first = False - else: - msg += ", " - msg += _unicode_decode('required by %s') % (node,) - elif node is not pkg: - for ppkg, patom in all_parents[child]: - if ppkg == node: - atom = patom.unevaluated_atom - break - - dep_strings = set() - for priority in self._dynamic_config.digraph.nodes[node][0][child]: - if priority.buildtime: - dep_strings.add(node.metadata["DEPEND"]) - if priority.runtime: - dep_strings.add(node.metadata["RDEPEND"]) - if priority.runtime_post: - dep_strings.add(node.metadata["PDEPEND"]) - - affecting_use = set() - for dep_str in dep_strings: - affecting_use.update(extract_affecting_use(dep_str, atom)) - - #Don't show flags as 'affecting' if the user can't change them, - affecting_use.difference_update(node.use.mask, \ - node.use.force) - - pkg_name = node.cpv - if affecting_use: - usedep = [] - for flag in affecting_use: - if flag in self._pkg_use_enabled(node): - usedep.append(flag) - else: - usedep.append("-"+flag) - pkg_name += "[%s]" % ",".join(usedep) - - if first: - first = False - else: - msg += ", " - msg += 'required by =%s' % pkg_name - - if node not in self._dynamic_config.digraph: - # The parent is not in the graph due to backtracking. - break - - # When traversing to parents, prefer arguments over packages - # since arguments are root nodes. Never traverse the same - # package twice, in order to prevent an infinite loop. - selected_parent = None - for parent in self._dynamic_config.digraph.parent_nodes(node): - if parent in traversed_nodes: - continue - if isinstance(parent, DependencyArg): - if self._dynamic_config.digraph.parent_nodes(parent): - selected_parent = parent - child = node - else: - if first: - first = False - else: - msg += ", " - msg += _unicode_decode( - 'required by %s (argument)') % (parent,) - selected_parent = None - break - else: - selected_parent = parent - child = node - node = selected_parent - msg += "\n" - return msg - unstable_keyword_msg = [] for pkg in self._dynamic_config._needed_unstable_keywords: self._show_merge_list() @@ -4942,7 +4937,7 @@ class depgraph(object): reason.unmask_hint.key == 'unstable keyword': keyword = reason.unmask_hint.value - unstable_keyword_msg.append(get_dep_chain(pkg)) + unstable_keyword_msg.append(self._get_dep_chain_as_comment(pkg)) unstable_keyword_msg.append("=%s %s\n" % (pkg.cpv, keyword)) use_changes_msg = [] @@ -4956,14 +4951,14 @@ class depgraph(object): adjustments.append(flag) else: adjustments.append("-" + flag) - use_changes_msg.append(get_dep_chain(pkg)) + use_changes_msg.append(self._get_dep_chain_as_comment(pkg)) use_changes_msg.append("=%s %s\n" % (pkg.cpv, " ".join(adjustments))) license_msg = [] for pkg, missing_licenses in self._dynamic_config._needed_license_changes.items(): self._show_merge_list() if pkg in self._dynamic_config.digraph: - license_msg.append(get_dep_chain(pkg)) + license_msg.append(self._get_dep_chain_as_comment(pkg)) license_msg.append("=%s %s\n" % (pkg.cpv, " ".join(sorted(missing_licenses)))) if unstable_keyword_msg: diff --git a/pym/portage/tests/resolver/test_old_dep_chain_display.py b/pym/portage/tests/resolver/test_old_dep_chain_display.py new file mode 100644 index 000000000..57f1ff184 --- /dev/null +++ b/pym/portage/tests/resolver/test_old_dep_chain_display.py @@ -0,0 +1,33 @@ +# Copyright 2010-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 OldDepChainDisplayTestCase(TestCase): + + def testOldDepChainDisplay(self): + ebuilds = { + "dev-libs/A-1": { "DEPEND": "foo? ( dev-libs/B[-bar] )", "IUSE": "+foo", "EAPI": "2" }, + "dev-libs/A-2": { "DEPEND": "foo? ( dev-libs/C )", "IUSE": "+foo", "EAPI": "1" }, + "dev-libs/B-1": { "IUSE": "bar", "DEPEND": "!bar? ( dev-libs/D[-baz] )", "EAPI": "2" }, + "dev-libs/C-1": { "KEYWORDS": "~x86" }, + "dev-libs/D-1": { "IUSE": "+baz", "EAPI": "1" }, + } + + test_cases = ( + ResolverPlaygroundTestCase( + ["=dev-libs/A-1"], + success = False), + ResolverPlaygroundTestCase( + ["=dev-libs/A-2"], + success = False), + ) + + playground = ResolverPlayground(ebuilds=ebuilds) + 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()