From 4b627a140461e498a74ca3ff0122ee2881400e8b Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Sat, 21 Nov 2009 02:38:39 +0000 Subject: Optimized the code for bug #288083 and make it handle more cases. Now Package 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 | 81 +++++++++++++++++++++++++++++++++++++++++++++++-- pym/_emerge/depgraph.py | 79 ++++++++++++++++++++--------------------------- pym/_emerge/search.py | 8 ++--- pym/_emerge/visible.py | 45 --------------------------- 4 files changed, 116 insertions(+), 97 deletions(-) delete mode 100644 pym/_emerge/visible.py (limited to 'pym') diff --git a/pym/_emerge/Package.py b/pym/_emerge/Package.py index dc8b975e6..6ab9be7ad 100644 --- a/pym/_emerge/Package.py +++ b/pym/_emerge/Package.py @@ -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: diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index dc7b7da87..966e27be4 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -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: diff --git a/pym/_emerge/search.py b/pym/_emerge/search.py index e5ad91da2..f36a249e0 100644 --- a/pym/_emerge/search.py +++ b/pym/_emerge/search.py @@ -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 index c50768dfb..000000000 --- a/pym/_emerge/visible.py +++ /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 -- cgit v1.2.3-1-g7c22