Bug #223447 - Adjust the "installed packages are masked" display to recognize
authorZac Medico <zmedico@gentoo.org>
Wed, 28 May 2008 08:31:06 +0000 (08:31 -0000)
committerZac Medico <zmedico@gentoo.org>
Wed, 28 May 2008 08:31:06 +0000 (08:31 -0000)
packages that are masked by keywords and are eligible for uninstallation by
depclean. This is a workaround for the fact that depclean may fail to
recognize that the package is eligible for uninstall due to differences in
visibility filtering which can lead to differences in || dep evaluation.
TODO: Share visibility code to fix this inconsistency.

svn path=/main/trunk/; revision=10465

pym/_emerge/__init__.py
pym/portage/__init__.py

index f5a94221a186a4f56ed9c5a3c71e46970407f6fc..61141d675c2bc35ab12caca81c6fc5d14460f497 100644 (file)
@@ -1990,7 +1990,7 @@ class depgraph(object):
                self._displayed_list = None
                self._pprovided_args = []
                self._missing_args = []
-               self._masked_installed = []
+               self._masked_installed = set()
                self._unsatisfied_deps_for_display = []
                self._unsatisfied_blockers_for_display = None
                self._circular_deps_for_display = None
@@ -2299,12 +2299,6 @@ class depgraph(object):
                                        del e
                                        return 0
 
-               if pkg.installed:
-                       # Warn if an installed package is masked and it
-                       # is pulled into the graph.
-                       if not visible(pkgsettings, pkg):
-                               self._masked_installed.append((pkg, pkgsettings))
-
                if args:
                        self._set_nodes.add(pkg)
 
@@ -3424,11 +3418,51 @@ class depgraph(object):
                                portdb = self.trees[myroot]["porttree"].dbapi
                                pkgsettings = self.pkgsettings[myroot]
                                final_db = self.mydbapi[myroot]
+
+                               graph_complete_for_root = "complete" in self.myparams or \
+                                       (myroot == self.target_root and \
+                                       ("deep" in self.myparams or "empty" in self.myparams) and \
+                                       not self._required_set_names.difference(self._sets))
+
                                blocker_cache = BlockerCache(myroot, vardb)
                                stale_cache = set(blocker_cache)
                                for pkg in vardb:
                                        cpv = pkg.cpv
                                        stale_cache.discard(cpv)
+
+                                       # Check for masked installed packages. For keyword
+                                       # mask there are a couple of common cases that are
+                                       # likely to generate unwanted noise:
+                                       #
+                                       #  * Packages missing /var/db/pkg/*/*/KEYWORDS entries
+                                       #    due to having been installed by an old version of
+                                       #    portage.
+                                       #
+                                       #  * Packages installed by overriding ACCEPT_KEYWORDS
+                                       #    via the environment.
+                                       #
+                                       # To avoid unwanted noise, only warn about keyword
+                                       # masks if all of the following are true:
+                                       #
+                                       #  * KEYWORDS is not empty (not installed by old portage).
+                                       #
+                                       #  * The graph is complete and the package has not been
+                                       #    pulled into the dependency graph. It's eligible for
+                                       #    depclean, but depclean may fail to recognize it as
+                                       #    such due to differences in visibility filtering which
+                                       #    can lead to differences in || dep evaluation.
+                                       #    TODO: Share visibility code to fix this inconsistency.
+
+                                       if pkg in final_db:
+                                               if not visible(pkgsettings, pkg):
+                                                       self._masked_installed.add(pkg)
+                                               elif graph_complete_for_root and \
+                                                       pkgsettings.getMissingKeywords(
+                                                       pkg.cpv, pkg.metadata) and \
+                                                       pkg.metadata["KEYWORDS"].split() and \
+                                                       not self.digraph.contains(pkg):
+                                                       self._masked_installed.add(pkg)
+
                                        blocker_atoms = None
                                        blockers = None
                                        if self.digraph.contains(pkg):
@@ -5088,8 +5122,9 @@ class depgraph(object):
                        sys.stderr.write("".join(msg))
 
                masked_packages = []
-               for pkg, pkgsettings in self._masked_installed:
-                       root_config = self.roots[pkg.root]
+               for pkg in self._masked_installed:
+                       root_config = pkg.root_config
+                       pkgsettings = root_config.settings
                        mreasons = get_masking_status(pkg, pkgsettings, root_config)
                        masked_packages.append((root_config, pkgsettings,
                                pkg.cpv, pkg.metadata, mreasons))
index 0abbbb81dc2e90db532c236904800ab36b861b1b..ed3000155ba9297ae0229b01a6c438b749622edf 100644 (file)
@@ -6180,11 +6180,6 @@ def getmaskingstatus(mycpv, settings=None, portdb=None):
                                kmask="~"+myarch
                                break
 
-       # Assume that the user doesn't want to be bothered about
-       # KEYWORDS of packages that are already installed.
-       if kmask and not installed:
-               rValue.append(kmask+" keyword")
-
        try:
                missing_licenses = settings.getMissingLicenses(mycpv, metadata)
                if missing_licenses:
@@ -6199,6 +6194,11 @@ def getmaskingstatus(mycpv, settings=None, portdb=None):
        except portage.exception.InvalidDependString, e:
                rValue.append("LICENSE: "+str(e))
 
+       # Only show KEYWORDS masks for installed packages
+       # if they're not masked for any other reason.
+       if kmask and (not installed or not rValue):
+               rValue.append(kmask+" keyword")
+
        return rValue