summaryrefslogtreecommitdiffstats
path: root/pym
diff options
context:
space:
mode:
authorSebastian Luther <SebastianLuther@gmx.de>2011-01-28 13:59:41 +0100
committerZac Medico <zmedico@gentoo.org>2011-01-28 13:13:08 -0800
commit5a9d387c25ff13500d5898cb58fdc2d3e6637204 (patch)
treed8d34cfc52dd19da150912079b0e664635232d89 /pym
parent12fda364c7d7fc6ce36f2a10bdcfc38adab27110 (diff)
downloadportage-5a9d387c25ff13500d5898cb58fdc2d3e6637204.tar.gz
portage-5a9d387c25ff13500d5898cb58fdc2d3e6637204.tar.bz2
portage-5a9d387c25ff13500d5898cb58fdc2d3e6637204.zip
Show use conditionals in old style dep chains
Diffstat (limited to 'pym')
-rw-r--r--pym/_emerge/depgraph.py247
-rw-r--r--pym/portage/tests/resolver/test_old_dep_chain_display.py33
2 files changed, 154 insertions, 126 deletions
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()