commit:     e309323f156528a8a79a1f755e1326e8880346b7
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Sat Mar 18 03:27:56 2017 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Sat Mar 18 09:30:18 2017 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=e309323f

emerge: fix --use-ebuild-visibility to reject binary packages (bug 612960)

Fix the --use-ebuild-visibility option to reject binary packages for
which ebuilds are either masked or unavailable. The included test case
fails without this fix.

X-Gentoo-bug: 612960
X-Gentoo-bug-url: https://bugs.gentoo.org/show_bug.cgi?id=612960
Acked-by: Brian Dolbec <dolsen <AT> gentoo.org>

 pym/_emerge/depgraph.py                            |  34 +++++-
 .../resolver/test_binary_pkg_ebuild_visibility.py  | 118 +++++++++++++++++++++
 2 files changed, 149 insertions(+), 3 deletions(-)

diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
index e94b96ce8..543f4dc78 100644
--- a/pym/_emerge/depgraph.py
+++ b/pym/_emerge/depgraph.py
@@ -4889,6 +4889,9 @@ class depgraph(object):
                vardb = self._frozen_config.roots[root].trees["vartree"].dbapi
                bindb = self._frozen_config.roots[root].trees["bintree"].dbapi
                dbs = self._dynamic_config._filtered_trees[root]["dbs"]
+               use_ebuild_visibility = self._frozen_config.myopts.get(
+                       '--use-ebuild-visibility', 'n') != 'n'
+
                for db, pkg_type, built, installed, db_keys in dbs:
                        if installed:
                                continue
@@ -4975,6 +4978,7 @@ class depgraph(object):
                                                                eapi=pkg.eapi):
                                                                
required_use_unsatisfied.append(pkg)
                                                                continue
+
                                                root_slot = (pkg.root, 
pkg.slot_atom)
                                                if pkg.built and root_slot in 
self._rebuild.rebuild_list:
                                                        mreasons = ["need to 
rebuild from source"]
@@ -4988,6 +4992,21 @@ class depgraph(object):
                                                        
self._dynamic_config.ignored_binaries.get(
                                                        pkg, 
{}).get("changed_deps")):
                                                        mreasons = ["changed 
deps"]
+                                               elif (pkg.built and 
use_ebuild_visibility and
+                                                       not 
self._equiv_ebuild_visible(pkg)):
+                                                       equiv_ebuild = 
self._equiv_ebuild(pkg)
+                                                       if equiv_ebuild is None:
+                                                               if 
portdb.cpv_exists(pkg.cpv):
+                                                                       
mreasons = ["ebuild corrupt"]
+                                                               else:
+                                                                       
mreasons = ["ebuild not available"]
+                                                       elif not mreasons:
+                                                               mreasons = 
get_masking_status(
+                                                                       
equiv_ebuild, pkgsettings, root_config,
+                                                                       
use=self._pkg_use_enabled(equiv_ebuild))
+                                                               if mreasons:
+                                                                       
metadata = equiv_ebuild._metadata
+
                                        masked_packages.append(
                                                (root_config, pkgsettings, cpv, 
repo, metadata, mreasons))
 
@@ -5548,6 +5567,14 @@ class depgraph(object):
                """
                return depth + n if isinstance(depth, int) else depth
 
+       def _equiv_ebuild(self, pkg):
+               try:
+                       return self._pkg(
+                               pkg.cpv, "ebuild", pkg.root_config, 
myrepo=pkg.repo)
+               except portage.exception.PackageNotFound:
+                       return next(self._iter_match_pkgs(pkg.root_config,
+                               "ebuild", Atom("=%s" % (pkg.cpv,))), None)
+
        def _equiv_ebuild_visible(self, pkg, autounmask_level=None):
                try:
                        pkg_eb = self._pkg(
@@ -6021,11 +6048,11 @@ class depgraph(object):
                                                # reinstall the same exact 
version only due
                                                # to a KEYWORDS mask. See bug 
#252167.
 
+                                               identical_binary = False
                                                if pkg.type_name != "ebuild" 
and matched_packages:
                                                        # Don't re-install a 
binary package that is
                                                        # identical to the 
currently installed package
                                                        # (see bug #354441).
-                                                       identical_binary = False
                                                        if usepkg and 
pkg.installed:
                                                                for 
selected_pkg in matched_packages:
                                                                        if 
selected_pkg.type_name == "binary" and \
@@ -6035,12 +6062,13 @@ class depgraph(object):
                                                                                
identical_binary = True
                                                                                
break
 
-                                                       if not identical_binary:
+                                               if not identical_binary and 
pkg.built:
                                                                # If the ebuild 
no longer exists or it's
                                                                # keywords have 
been dropped, reject built
                                                                # instances 
(installed or binary).
                                                                # If 
--usepkgonly is enabled, assume that
-                                                               # the ebuild 
status should be ignored.
+                                                               # the ebuild 
status should be ignored unless
+                                                               # 
--use-ebuild-visibility has been specified.
                                                                if not 
use_ebuild_visibility and (usepkgonly or useoldpkg):
                                                                        if 
pkg.installed and pkg.masks:
                                                                                
continue

diff --git a/pym/portage/tests/resolver/test_binary_pkg_ebuild_visibility.py 
b/pym/portage/tests/resolver/test_binary_pkg_ebuild_visibility.py
new file mode 100644
index 000000000..ea65abded
--- /dev/null
+++ b/pym/portage/tests/resolver/test_binary_pkg_ebuild_visibility.py
@@ -0,0 +1,118 @@
+# Copyright 2017 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 BinaryPkgEbuildVisibilityTestCase(TestCase):
+
+       def testBinaryPkgEbuildVisibility(self):
+
+               binpkgs = {
+                       "app-misc/foo-3" : {},
+                       "app-misc/foo-2" : {},
+                       "app-misc/foo-1" : {},
+               }
+
+               ebuilds = {
+                       "app-misc/foo-2" : {},
+                       "app-misc/foo-1" : {},
+               }
+
+               installed = {
+                       "app-misc/foo-1" : {},
+               }
+
+               world = ["app-misc/foo"]
+
+               test_cases = (
+
+                       # Test bug #612960, where --use-ebuild-visibility failed
+                       # to reject binary packages for which ebuilds were not
+                       # available.
+                       ResolverPlaygroundTestCase(
+                               ["@world"],
+                               options = {
+                                       "--update": True,
+                                       "--deep": True,
+                                       "--use-ebuild-visibility": 'y',
+                                       "--usepkgonly": True,
+                               },
+                               success = True,
+                               mergelist = [
+                                       '[binary]app-misc/foo-2',
+                               ],
+                       ),
+
+                       ResolverPlaygroundTestCase(
+                               ["@world"],
+                               options = {
+                                       "--update": True,
+                                       "--deep": True,
+                                       "--usepkgonly": True,
+                               },
+                               success = True,
+                               mergelist = [
+                                       '[binary]app-misc/foo-3',
+                               ],
+                       ),
+
+                       ResolverPlaygroundTestCase(
+                               ["@world"],
+                               options = {
+                                       "--update": True,
+                                       "--deep": True,
+                                       "--usepkg": True,
+                               },
+                               success = True,
+                               mergelist = [
+                                       '[binary]app-misc/foo-2',
+                               ],
+                       ),
+
+                       ResolverPlaygroundTestCase(
+                               ["=app-misc/foo-3"],
+                               options = {
+                                       "--use-ebuild-visibility": 'y',
+                                       "--usepkgonly": True,
+                               },
+                               success = False,
+                       ),
+
+                       ResolverPlaygroundTestCase(
+                               ["app-misc/foo"],
+                               options = {
+                                       "--use-ebuild-visibility": 'y',
+                                       "--usepkgonly": True,
+                               },
+                               success = True,
+                               mergelist = [
+                                       '[binary]app-misc/foo-2',
+                               ],
+                       ),
+
+                       ResolverPlaygroundTestCase(
+                               ["app-misc/foo"],
+                               options = {
+                                       "--usepkgonly": True,
+                               },
+                               success = True,
+                               mergelist = [
+                                       '[binary]app-misc/foo-3',
+                               ],
+                       ),
+               )
+
+               playground = ResolverPlayground(binpkgs=binpkgs, 
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()
+

Reply via email to