Optimized the code for bug #288083 and make it handle more cases. Now Package v2.2_rc51
authorZac Medico <zmedico@gentoo.org>
Sat, 21 Nov 2009 02:38:39 +0000 (02:38 -0000)
committerZac Medico <zmedico@gentoo.org>
Sat, 21 Nov 2009 02:38:39 +0000 (02:38 -0000)
instances have 'visible' and 'masks' attributes, since this information needs
to be accessed in more places now.

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

pym/_emerge/Package.py
pym/_emerge/depgraph.py
pym/_emerge/search.py
pym/_emerge/visible.py [deleted file]

index dc8b975e60a4f258c2e3ad82d6abcafd0faa3a66..6ab9be7adbbcd3a15044d2d5b16d003d021ef09f 100644 (file)
@@ -22,8 +22,8 @@ class Package(Task):
                "installed", "metadata", "onlydeps", "operation",
                "root_config", "type_name",
                "category", "counter", "cp", "cpv_split",
-               "inherited", "invalid", "iuse", "mtime",
-               "pf", "pv_split", "root", "slot", "slot_atom",) + \
+               "inherited", "invalid", "iuse", "masks", "mtime",
+               "pf", "pv_split", "root", "slot", "slot_atom", "visible",) + \
        ("_use",)
 
        metadata_keys = [
@@ -50,6 +50,83 @@ class Package(Task):
                self.category, self.pf = portage.catsplit(self.cpv)
                self.cpv_split = portage.catpkgsplit(self.cpv)
                self.pv_split = self.cpv_split[1:]
+               self.masks = self._masks()
+               self.visible = self._visible(self.masks)
+
+       def _masks(self):
+               masks = {}
+               settings = self.root_config.settings
+
+               if self.invalid is not None:
+                       masks['invalid'] = self.invalid
+
+               if not settings._accept_chost(self.cpv, self.metadata):
+                       masks['CHOST'] = self.metadata['CHOST']
+
+               eapi = self.metadata["EAPI"]
+               if not portage.eapi_is_supported(eapi):
+                       masks['EAPI.unsupported'] = eapi
+               if portage._eapi_is_deprecated(eapi):
+                       masks['EAPI.deprecated'] = eapi
+
+               missing_keywords = settings._getMissingKeywords(
+                       self.cpv, self.metadata)
+               if missing_keywords:
+                       masks['KEYWORDS'] = missing_keywords
+
+               try:
+                       missing_properties = settings._getMissingProperties(
+                               self.cpv, self.metadata)
+                       if missing_properties:
+                               masks['PROPERTIES'] = missing_properties
+               except portage.exception.InvalidDependString:
+                       # already recorded as 'invalid'
+                       pass
+
+               mask_atom = settings._getMaskAtom(self.cpv, self.metadata)
+               if mask_atom is not None:
+                       masks['package.mask'] = mask_atom
+
+               system_mask = settings._getProfileMaskAtom(
+                       self.cpv, self.metadata)
+               if system_mask is not None:
+                       masks['profile.system'] = system_mask
+
+               try:
+                       missing_licenses = settings._getMissingLicenses(
+                               self.cpv, self.metadata)
+                       if missing_licenses:
+                               masks['LICENSE'] = missing_licenses
+               except portage.exception.InvalidDependString:
+                       # already recorded as 'invalid'
+                       pass
+
+               if not masks:
+                       masks = None
+
+               return masks
+
+       def _visible(self, masks):
+
+               if masks is not None:
+
+                       if 'EAPI.unsupported' in masks:
+                               return False
+
+                       if not self.installed and ( \
+                               'invalid' in masks or \
+                               'CHOST' in masks or \
+                               'EAPI.deprecated' in masks or \
+                               'KEYWORDS' in masks or \
+                               'PROPERTIES' in masks):
+                               return False
+
+                       if 'package.mask' in masks or \
+                               'profile.system' in masks or \
+                               'LICENSE' in masks:
+                               return False
+
+               return True
 
        def _invalid_metadata(self, msg_type, msg):
                if self.invalid is None:
index dc7b7da8725d1fd85bef5b1f37efc7050c1b79f0..966e27be4eee9c2395c384bd89ac4772195b5913 100644 (file)
@@ -49,7 +49,6 @@ from _emerge.search import search
 from _emerge.SetArg import SetArg
 from _emerge.show_invalid_depstring_notice import show_invalid_depstring_notice
 from _emerge.UnmergeDepPriority import UnmergeDepPriority
-from _emerge.visible import visible
 
 if sys.hexversion >= 0x3000000:
        basestring = str
@@ -74,6 +73,7 @@ class _frozen_depgraph_config(object):
                self.roots = {}
                # All Package instances
                self._pkg_cache = {}
+               self._highest_license_masked = {}
                for myroot in trees:
                        self.trees[myroot] = {}
                        # Create a RootConfig instance that references
@@ -989,6 +989,7 @@ class depgraph(object):
                                self._dynamic_config._slot_pkg_map[pkg.root][pkg.slot_atom] = pkg
                                self._dynamic_config.mydbapi[pkg.root].cpv_inject(pkg)
                                self._dynamic_config._filtered_trees[pkg.root]["porttree"].dbapi._clear_cache()
+                               self._check_masks(pkg)
 
                        if not pkg.installed:
                                # Allow this package to satisfy old-style virtuals in case it
@@ -1047,6 +1048,17 @@ class depgraph(object):
                        dep_stack.append(pkg)
                return 1
 
+       def _check_masks(self, pkg):
+
+               slot_key = (pkg.root, pkg.slot_atom)
+
+               # Check for upgrades in the same slot that are
+               # masked due to a LICENSE change in a newer
+               # version that is not masked for any other reason.
+               other_pkg = self._frozen_config._highest_license_masked.get(slot_key)
+               if other_pkg is not None and pkg < other_pkg:
+                       self._dynamic_config._masked_license_updates.add(other_pkg)
+
        def _add_parent_atom(self, pkg, parent_atom):
                parent_atoms = self._dynamic_config._parent_atoms.get(pkg)
                if parent_atoms is None:
@@ -2350,7 +2362,7 @@ class depgraph(object):
                pkg, existing = ret
                if pkg is not None:
                        settings = pkg.root_config.settings
-                       if visible(settings, pkg) and not (pkg.installed and \
+                       if pkg.visible and not (pkg.installed and \
                                settings._getMissingKeywords(pkg.cpv, pkg.metadata)):
                                self._dynamic_config._visible_pkgs[pkg.root].cpv_inject(pkg)
                return ret
@@ -2425,12 +2437,9 @@ class depgraph(object):
                                                # here, packages that have been masked since they
                                                # were installed can be automatically downgraded
                                                # to an unmasked version.
-                                               try:
-                                                       if not visible(pkgsettings, pkg):
-                                                               continue
-                                               except portage.exception.InvalidDependString:
-                                                       if not installed:
-                                                               continue
+
+                                               if not pkg.visible:
+                                                       continue
 
                                                # Enable upgrade or downgrade to a version
                                                # with visible KEYWORDS when the installed
@@ -2463,7 +2472,7 @@ class depgraph(object):
                                                                        except portage.exception.PackageNotFound:
                                                                                continue
                                                                        else:
-                                                                               if not visible(pkgsettings, pkg_eb):
+                                                                               if not pkg_eb.visible:
                                                                                        continue
 
                                        # Calculation of USE for unbuilt ebuilds is relatively
@@ -2762,6 +2771,14 @@ class depgraph(object):
                                installed=installed, metadata=metadata, onlydeps=onlydeps,
                                root_config=root_config, type_name=type_name)
                        self._frozen_config._pkg_cache[pkg] = pkg
+
+                       if not pkg.visible and \
+                               'LICENSE' in pkg.masks and len(pkg.masks) == 1:
+                               slot_key = (pkg.root, pkg.slot_atom)
+                               other_pkg = self._frozen_config._highest_license_masked.get(slot_key)
+                               if other_pkg is None or pkg > other_pkg:
+                                       self._frozen_config._highest_license_masked[slot_key] = pkg
+
                return pkg
 
        def _validate_blockers(self):
@@ -2806,35 +2823,11 @@ class depgraph(object):
                                        # packages masked by license, since the user likely wants
                                        # to adjust ACCEPT_LICENSE.
                                        if pkg in final_db:
-                                               if pkg_in_graph and not visible(pkgsettings, pkg):
-                                                       self._dynamic_config._masked_installed.add(pkg)
-                                               elif pkgsettings._getMissingLicenses(pkg.cpv, pkg.metadata):
+                                               if not pkg.visible and \
+                                                       (pkg_in_graph or 'LICENSE' in pkg.masks):
                                                        self._dynamic_config._masked_installed.add(pkg)
-                                               elif pkg_in_graph or complete or deep:
-                                                       # Check for upgrades in the same slot that are
-                                                       # masked due to a LICENSE change in a newer
-                                                       # version that is not masked for any other reason.
-                                                       # Only do this for packages that are already in
-                                                       # the graph, or complete or deep graphs, since
-                                                       # otherwise it is likely a waste of time.
-                                                       got_mask = False
-                                                       for db, pkg_type, built, installed, db_keys in dbs:
-                                                               if installed:
-                                                                       continue
-                                                               if got_mask:
-                                                                       break
-                                                               for upgrade_pkg in self._iter_match_pkgs(
-                                                                       root_config, pkg_type, pkg.slot_atom):
-                                                                       if upgrade_pkg <= pkg:
-                                                                               break
-                                                                       if not visible(pkgsettings,
-                                                                               upgrade_pkg, ignore=('LICENSE',)):
-                                                                               continue
-                                                                       if pkgsettings._getMissingLicenses(
-                                                                               upgrade_pkg.cpv, upgrade_pkg.metadata):
-                                                                               self._dynamic_config._masked_license_updates.add(upgrade_pkg)
-                                                                               got_mask = True
-                                                                               break
+                                               else:
+                                                       self._check_masks(pkg)
 
                                        blocker_atoms = None
                                        blockers = None
@@ -4992,8 +4985,7 @@ class depgraph(object):
                                        continue
                                raise
 
-                       if "merge" == pkg.operation and \
-                               not visible(root_config.settings, pkg):
+                       if "merge" == pkg.operation and not pkg.visible:
                                if skip_masked:
                                        masked_tasks.append(Dependency(root=pkg.root, parent=pkg))
                                else:
@@ -5265,13 +5257,8 @@ class _dep_check_composite_db(portage.dbapi):
                                arg = None
                        if arg:
                                return False
-               if pkg.installed:
-                       try:
-                               if not visible(
-                                       self._depgraph._frozen_config.pkgsettings[pkg.root], pkg):
-                                       return False
-                       except portage.exception.InvalidDependString:
-                               pass
+               if pkg.installed and not pkg.visible:
+                       return False
                in_graph = self._depgraph._dynamic_config._slot_pkg_map[
                        self._root].get(pkg.slot_atom)
                if in_graph is None:
index e5ad91da2d56ab94a4fb93a5af24bb3693c64474..f36a249e0bf79c10650814ba11a1fcd30d8199f1 100644 (file)
@@ -11,7 +11,6 @@ from portage.output import  bold, bold as white, darkgreen, green, red
 from portage.util import writemsg_stdout
 
 from _emerge.Package import Package
-from _emerge.visible import visible
 
 class search(object):
 
@@ -111,9 +110,10 @@ class search(object):
                        pkg_type = "installed"
                elif built:
                        pkg_type = "binary"
-               return visible(self.settings,
-                       Package(type_name=pkg_type, root_config=self.root_config,
-                       cpv=cpv, built=built, installed=installed, metadata=metadata))
+               return Package(type_name=pkg_type,
+                       root_config=self.root_config,
+                       cpv=cpv, built=built, installed=installed,
+                       metadata=metadata).visible
 
        def _xmatch(self, level, atom):
                """
diff --git a/pym/_emerge/visible.py b/pym/_emerge/visible.py
deleted file mode 100644 (file)
index c50768d..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright 1999-2009 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-# $Id$
-
-import portage
-
-def visible(pkgsettings, pkg, ignore=None):
-       """
-       Check if a package is visible. This can raise an InvalidDependString
-       exception if LICENSE is invalid.
-       TODO: optionally generate a list of masking reasons
-       @rtype: Boolean
-       @returns: True if the package is visible, False otherwise.
-       """
-       if not pkg.metadata["SLOT"]:
-               return False
-       if not pkg.installed:
-               if pkg.invalid:
-                       return False
-               if not pkgsettings._accept_chost(pkg.cpv, pkg.metadata):
-                       return False
-       eapi = pkg.metadata["EAPI"]
-       if not portage.eapi_is_supported(eapi):
-               return False
-       if not pkg.installed:
-               if portage._eapi_is_deprecated(eapi):
-                       return False
-               if pkgsettings._getMissingKeywords(pkg.cpv, pkg.metadata):
-                       return False
-               try:
-                       if pkgsettings._getMissingProperties(pkg.cpv, pkg.metadata):
-                               return False
-               except portage.exception.InvalidDependString:
-                       return False
-       if pkgsettings._getMaskAtom(pkg.cpv, pkg.metadata):
-               return False
-       if pkgsettings._getProfileMaskAtom(pkg.cpv, pkg.metadata):
-               return False
-       try:
-               if pkgsettings._getMissingLicenses(pkg.cpv, pkg.metadata):
-                       if ignore is None or 'LICENSE' not in ignore:
-                               return False
-       except portage.exception.InvalidDependString:
-               return False
-       return True