Merge pull request #31 from Enlik/conflict-print-revdeps

[solo.commands,lib] display packages that pull in conflicting ones
This commit is contained in:
Fabio Erculiani
2016-08-30 20:17:35 +02:00
committed by GitHub
4 changed files with 51 additions and 9 deletions
+31 -3
View File
@@ -20,7 +20,7 @@ from entropy.const import const_convert_to_unicode, etpConst, \
const_debug_write, const_mkstemp
from entropy.i18n import _, ngettext
from entropy.output import darkgreen, blue, purple, teal, brown, bold, \
darkred, readtext, is_interactive
darkred, green, readtext, is_interactive
from entropy.exceptions import EntropyPackageException, \
DependenciesCollision, DependenciesNotFound
from entropy.services.client import WebService
@@ -498,7 +498,7 @@ class SoloManage(SoloCommand):
return None, None
except DependenciesCollision as exc:
col_deps = exc.value
col_deps, pkg_revdeps = exc.value
entropy_client.output(
"%s:" % (blue(_("Conflicting packages were pulled in")),),
@@ -507,7 +507,8 @@ class SoloManage(SoloCommand):
entropy_client.output("", level="warning")
for pkg_matches in col_deps:
for pkg_id, pkg_repo in pkg_matches:
for pkg_match in pkg_matches:
pkg_id, pkg_repo = pkg_match
repo = entropy_client.open_repository(pkg_repo)
entropy_client.output(
"%s%s%s" % (
@@ -516,6 +517,33 @@ class SoloManage(SoloCommand):
purple(pkg_repo),),
header=brown(" # "),
level="warning")
if not pkg_revdeps[pkg_match]:
entropy_client.output(
"(%s: %s)" % (
green(_("required by")),
# Conflicting dependencies could have been
# specified by user, in which case they were
# not pulled in by anything.
teal(_("(no reverse dependencies)")),),
header=blue(" "),
level="info")
continue
for pkg_revdep in pkg_revdeps[pkg_match]:
pkg_revdep_id, pkg_revdep_repo = pkg_revdep
revdep_repo = \
entropy_client.open_repository(pkg_revdep_repo)
entropy_client.output(
"(%s: %s%s%s)" % (
green(_("required by")),
teal(revdep_repo.retrieveAtom(pkg_revdep_id)),
darkred(etpConst['entropyrepoprefix']),
purple(pkg_revdep_repo),),
header=blue(" "),
level="info")
entropy_client.output("", level="warning")
entropy_client.output(
+15 -3
View File
@@ -2287,6 +2287,7 @@ class CalculatorsMixin:
# now check and report dependencies with colliding scope and in case,
# raise DependenciesCollision, containing information about collisions
# and what requires the packages involved
_dup_deps_collisions = {}
for _level, _deps in deptree.items():
for pkg_id, pkg_repo in _deps:
@@ -2295,9 +2296,18 @@ class CalculatorsMixin:
ks_set.add((pkg_id, pkg_repo))
_colliding_deps = [x for x in _dup_deps_collisions.values() if \
len(x) > 1]
if _colliding_deps:
_pkg_revdeps = {}
for _pkg_matches in _colliding_deps:
for _pkg_match in _pkg_matches:
_pkg_node = graph.get_node(_pkg_match)
_pkg_revdeps[_pkg_match] = [x.origin().item() for \
x in _pkg_node.arches() if \
not _pkg_node.is_arch_outgoing(x)]
graph.destroy()
raise DependenciesCollision(_colliding_deps)
raise DependenciesCollision((_colliding_deps, _pkg_revdeps))
# now use the ASAP herustic to anticipate post-dependencies
# as much as possible
@@ -3806,8 +3816,10 @@ class CalculatorsMixin:
@raise DependenciesCollision: packages pulled in conflicting depedencies
perhaps sharing the same key and slot (but different version).
In this case, user should mask one or the other by hand.
The value encapsulated .value object attribute contains the list of
colliding package (list of lists).
The value encapsulated .value object attribute contains tuple of two
elements: the list of colliding package (list of lists), and a
dictionary with information about each package's (first level) reverse
dependencies
@raise DependenciesNotFound: one or more dependencies required are not
found. The encapsulated .value object attribute contains a list of
not found dependencies.
+3 -1
View File
@@ -54,7 +54,9 @@ class DependenciesCollision(EntropyException):
"""
During dependencies calculation, dependencies were pulled in in the same
"scope" (package key + package slot),
list of lists (set) of colliding dependencies are in the .value attribute
two-element tuple of:
list of lists (set) of colliding dependencies are in the .value attribute,
dictionary mapping dependency to its (first level) reverse dependency
"""
class DependenciesNotRemovable(EntropyException):
+2 -2
View File
@@ -1914,7 +1914,7 @@ class RigoDaemonService(dbus.service.Object):
except DependenciesCollision as dcol:
write_output(
"_process_upgrade_merge_action, DependenciesCollision: "
"%s" % (dcol,))
"%s" % (dcol[0],))
outcome = \
AppTransactionOutcome.DEPENDENCIES_COLLISION_ERROR
return outcome
@@ -2241,7 +2241,7 @@ class RigoDaemonService(dbus.service.Object):
except DependenciesCollision as dcol:
write_output(
"_process_install_action, DependenciesCollision: "
"%s" % (dcol,))
"%s" % (dcol[0],))
# this should never happen since client executes this
# before us
outcome = \