summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2010-08-25 20:12:13 -0700
committerZac Medico <zmedico@gentoo.org>2010-08-25 20:12:13 -0700
commitd54fbed5b538cca5986e783c271cfd9cf679198d (patch)
tree7ef70f209390d79c23fd5335953c8a63e8712a03
parentd5490ca81fec08bad27414979305cc9a50c56edd (diff)
downloadportage-d54fbed5b538cca5986e783c271cfd9cf679198d.tar.gz
portage-d54fbed5b538cca5986e783c271cfd9cf679198d.tar.bz2
portage-d54fbed5b538cca5986e783c271cfd9cf679198d.zip
Bug #334365 - Mask packages with invalid metadata as early as possible,
so that the depgraph won't select them unless they are already installed and there is no other choice. This should trigger automatic reinstallation of installed packages that have invalid metadata.
-rw-r--r--pym/_emerge/Package.py66
-rw-r--r--pym/_emerge/depgraph.py21
2 files changed, 73 insertions, 14 deletions
diff --git a/pym/_emerge/Package.py b/pym/_emerge/Package.py
index 640f8bca1..557dda5c5 100644
--- a/pym/_emerge/Package.py
+++ b/pym/_emerge/Package.py
@@ -1,14 +1,15 @@
# Copyright 1999-2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-import re
import sys
from itertools import chain
import portage
from portage.cache.mappings import slot_dict_class
-from portage.dep import isvalidatom, use_reduce, \
+from portage.dep import Atom, isvalidatom, use_reduce, \
paren_enclose, _slot_re
-from portage.eapi import eapi_has_iuse_defaults, eapi_has_required_use
+from portage.eapi import eapi_has_src_uri_arrows, eapi_has_slot_deps, \
+ eapi_has_use_deps, eapi_has_strong_blocks, eapi_has_iuse_defaults, \
+ eapi_has_required_use, eapi_has_use_dep_defaults
from _emerge.Task import Task
if sys.hexversion >= 0x3000000:
@@ -33,6 +34,8 @@ class Package(Task):
"repository", "PROPERTIES", "RESTRICT", "SLOT", "USE",
"_mtime_", "DEFINED_PHASES", "REQUIRED_USE"]
+ _dep_keys = ('DEPEND', 'PDEPEND', 'RDEPEND',)
+
def __init__(self, **kwargs):
Task.__init__(self, **kwargs)
self.root = self.root_config.root
@@ -60,9 +63,66 @@ 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._validate_deps()
self.masks = self._masks()
self.visible = self._visible(self.masks)
+ def _validate_deps(self):
+ """
+ Validate deps. This does not trigger USE calculation since that
+ is expensive for ebuilds and therefore we want to avoid doing
+ in unnecessarily (like for masked packages).
+ """
+ eapi = self.metadata['EAPI']
+ for k in self._dep_keys:
+ v = self.metadata.get(k)
+ if not v:
+ continue
+ try:
+ atoms = portage.dep.use_reduce(v, matchall=True, flat=True,
+ is_valid_flag=self.iuse.is_valid_flag, token_class=Atom)
+ except portage.exception.InvalidDependString as e:
+ self._invalid_metadata(k + ".syntax", "%s: %s" % (k, e))
+ else:
+ for atom in atoms:
+ if not isinstance(atom, Atom):
+ continue
+
+ if atom.slot and not eapi_has_slot_deps(eapi):
+ self._invalid_metadata('EAPI.incompatible',
+ ("%s slot dependency" + \
+ " not supported with EAPI='%s':" + \
+ " '%s'") % (k, eapi, atom))
+
+ if atom.use and not eapi_has_use_deps(eapi):
+ self._invalid_metadata('EAPI.incompatible',
+ ("%s use dependency" + \
+ " not supported with EAPI='%s':" + \
+ " '%s'") % (k, eapi, atom))
+
+ if atom.use and (atom.use.missing_enabled or atom.use.missing_disabled) and \
+ not eapi_has_use_dep_defaults(eapi):
+ self._invalid_metadata('EAPI.incompatible',
+ ("%s use dependency" + \
+ " not supported with EAPI='%s':" + \
+ " '%s'") % (k, eapi, atom))
+
+ if atom.blocker and atom.blocker.overlap.forbid \
+ and not eapi_has_strong_blocks(eapi):
+ self._invalid_metadata('EAPI.incompatible',
+ ("%s new blocker syntax" + \
+ " not supported with EAPI='%s':" + \
+ " '%s'") % (k, eapi, atom))
+
+ k = 'SRC_URI'
+ v = self.metadata.get(k)
+ if v:
+ try:
+ use_reduce(v, matchall=True, flat=True, is_src_uri=True,
+ allow_src_uri_file_renames=eapi_has_src_uri_arrows(eapi))
+ except portage.exception.InvalidDependString as e:
+ self._invalid_metadata(k + ".syntax", "%s: %s" % (k, e))
+
def copy(self):
return Package(built=self.built, cpv=self.cpv, depth=self.depth,
installed=self.installed, metadata=self._raw_metadata,
diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
index d0d5386a1..435cc1a98 100644
--- a/pym/_emerge/depgraph.py
+++ b/pym/_emerge/depgraph.py
@@ -1033,16 +1033,14 @@ class depgraph(object):
# TODO: For installed package, save any InvalidDependString
# info in dynamic_config and wait until display_problems()
- # to show it. For packages that aren't installed, we should
- # validate and mask them before they are selected.
+ # to show it.
try:
dep_string = portage.dep.use_reduce(dep_string,
uselist=self._pkg_use_enabled(pkg), is_valid_flag=pkg.iuse.is_valid_flag)
except portage.exception.InvalidDependString as e:
if not pkg.installed:
- # TODO: validate and mask this before it's selected
- show_invalid_depstring_notice(pkg, dep_string, str(e))
- return 0
+ # should have been masked before it was selected
+ raise
del e
# Try again, but omit the is_valid_flag argument, since
@@ -1067,9 +1065,8 @@ class depgraph(object):
del e
continue
- # TODO: validate and mask this before it's selected
- show_invalid_depstring_notice(pkg, dep_string, str(e))
- return 0
+ # should have been masked before it was selected
+ raise
if not dep_string:
continue
@@ -1122,11 +1119,13 @@ class depgraph(object):
dep_string, myuse=self._pkg_use_enabled(pkg), parent=pkg,
strict=strict, priority=dep_priority)
except portage.exception.InvalidDependString as e:
- show_invalid_depstring_notice(pkg, dep_string, str(e))
- del e
if pkg.installed:
+ # TODO: show in display_problems()
+ show_invalid_depstring_notice(pkg, dep_string, str(e))
return 1
- return 0
+
+ # should have been masked before it was selected
+ raise
if debug:
writemsg_level("Candidates: %s\n" % \