On Fri, 17 Mar 2017 01:18:19 -0700
Zac Medico <zmed...@gentoo.org> wrote:

> Fix check_reverse_dependencies to ignore direct circular dependencies,
> since these dependencies tend to prevent updates of packages. This
> solves a missed update from llvm:0 to llvm:4 when clang is not in the
> world file, as demonstrated by the included test case.
> 
> X-Gentoo-bug: 612874
> X-Gentoo-bug-url: https://bugs.gentoo.org/show_bug.cgi?id=612874
> ---
>  pym/_emerge/depgraph.py                            | 31
> ++++++++++++----- .../resolver/test_slot_operator_exclusive_slots.py
> | 39 ++++++++++++++++++++++
> pym/portage/util/digraph.py                        |  6 ++++ 3 files
> changed, 68 insertions(+), 8 deletions(-)
> 
> diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
> index f4145d0..e94b96c 100644
> --- a/pym/_emerge/depgraph.py
> +++ b/pym/_emerge/depgraph.py
> @@ -1844,14 +1844,29 @@ class depgraph(object):
>                                       if (not
> self._too_deep(parent.depth) and not
> self._frozen_config.excluded_pkgs. findAtomForPackage(parent,
> -
> modified_use=self._pkg_use_enabled(parent)) and
> -
> (self._upgrade_available(parent) or
> -                                             (parent.installed
> and self._in_blocker_conflict(parent)))):
> -                                             # This parent may be
> irrelevant, since an
> -                                             # update is
> available (see bug 584626), or
> -                                             # it could be
> uninstalled in order to solve
> -                                             # a blocker conflict
> (bug 612772).
> -                                             continue
> +
> modified_use=self._pkg_use_enabled(parent))):
> +                                             # Check for common
> reasons that the parent's
> +                                             # dependency might
> be irrelevant.
> +                                             if
> self._upgrade_available(parent):
> +                                                     # This
> parent could be replaced by
> +                                                     # an upgrade
> (bug 584626).
> +                                                     continue
> +                                             if parent.installed
> and self._in_blocker_conflict(parent):
> +                                                     # This
> parent could be uninstalled in order
> +                                                     # to solve a
> blocker conflict (bug 612772).
> +                                                     continue
> +                                             if
> self._dynamic_config.digraph.has_edge(parent,
> +
> existing_pkg):
> +                                                     # There is a
> direct circular dependency between
> +                                                     # parent and
> existing_pkg. This type of
> +                                                     #
> relationship tends to prevent updates
> +                                                     # of
> packages (bug 612874). Since candidate_pkg
> +                                                     # is
> available, we risk a missed update if we
> +                                                     # don't try
> to eliminate this parent from the
> +                                                     # graph.
> Therefore, we give candidate_pkg a
> +                                                     # chance,
> and assume that it will be masked
> +                                                     # by
> backtracking if necessary.
> +                                                     continue
>  
>                               atom_set =
> InternalPackageSet(initial_atoms=(atom,), allow_repo=True)
> diff --git
> a/pym/portage/tests/resolver/test_slot_operator_exclusive_slots.py
> b/pym/portage/tests/resolver/test_slot_operator_exclusive_slots.py
> index 2ab379c..689ed31 100644 ---
> a/pym/portage/tests/resolver/test_slot_operator_exclusive_slots.py
> +++
> b/pym/portage/tests/resolver/test_slot_operator_exclusive_slots.py @@
> -107,3 +107,42 @@ class SlotOperatorExclusiveSlotsTestCase(TestCase):
> test_case.fail_msg) finally: playground.cleanup() +
> +
> +             world = ["media-libs/mesa"]
> +
> +             test_cases = (
> +
> +                     # Test bug #612874, where a direct circular
> dependency
> +                     # between llvm-3.9.1 and clang-3.9.1-r100
> causes a
> +                     # missed update from llvm:0 to llvm:4. Since
> llvm:4 does
> +                     # not have a dependency on clang, the
> upgrade from llvm:0
> +                     # to llvm:4 makes the installed
> sys-devel/clang-3.9.1-r100
> +                     # instance eligible for removal by emerge
> --depclean, which
> +                     # explains why clang does not appear in the
> mergelist.
> +                     ResolverPlaygroundTestCase(
> +                             ["@world"],
> +                             options = {"--update": True,
> "--deep": True},
> +                             success = True,
> +                             ambiguous_merge_order = True,
> +                             mergelist = [
> +                                     'sys-devel/llvm-4.0.0',
> +                                     (
> +                                             'media-libs/mesa-17.0.1',
> +                                             
> '[uninstall]sys-devel/llvm-3.9.1',
> +                                             '!sys-devel/llvm:0',
> +                                     )
> +                             ],
> +                     ),
> +
> +             )
> +
> +             playground = ResolverPlayground(ebuilds=ebuilds,
> +                     installed=installed, world=world)
> +             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()
> diff --git a/pym/portage/util/digraph.py b/pym/portage/util/digraph.py
> index 4a9cb43..b6be0c9 100644
> --- a/pym/portage/util/digraph.py
> +++ b/pym/portage/util/digraph.py
> @@ -93,6 +93,12 @@ class digraph(object):
>                       del self.nodes[node]
>               self.order = order
>  
> +     def has_edge(self, child, parent):
> +             """
> +             Return True if the given edge exists.
> +             """
> +             return child in self.nodes[parent][0]
> +
>       def remove_edge(self, child, parent):
>               """
>               Remove edge in the direction from child to parent.
> Note that it is


Looks good

-- 
Brian Dolbec <dolsen>


Reply via email to