Merged from trunk -r13690:13696
authorFabian Groffen <grobian@gentoo.org>
Sun, 28 Jun 2009 13:10:08 +0000 (13:10 -0000)
committerFabian Groffen <grobian@gentoo.org>
Sun, 28 Jun 2009 13:10:08 +0000 (13:10 -0000)
   | 13691   | * Add a Package.invalid attribute to store messages about    |
   | zmedico | invalid LICENSE, PROPERTIES, PROVIDE, and RESTRICT metadata. |
   |         | Use it to mask invalid packages when necessary. * Evaluate   |
   |         | USE conditional values in Package.metadata when the are      |
   |         | accessed.                                                    |

   | 13692   | Add a Package.metadata.properties attribute containing a     |
   | zmedico | list of enabled PROPERTIES values.                           |

   | 13693   | Add a Package.metadata.restrict attribute containing a list  |
   | zmedico | of enabled RESTRICT values.                                  |

   | 13694   | Make config.regenerate() detect api-level updates to         |
   | zmedico | ACCEPT_LICENSE, for use in implementing the "free" filter    |
   |         | for the packagekit backend.                                  |

   | 13695   | Make dbapi.cp_list() raise NotImplementedError.              |
   | zmedico |                                                              |

   | 13696   | Use @property instead of __getattribute__ to implement lazy  |
   | zmedico | Package.iuse.regex initialization.                           |

svn path=/main/branches/prefix/; revision=13718

pym/_emerge/EbuildFetchonly.py
pym/_emerge/Package.py
pym/_emerge/Scheduler.py
pym/_emerge/depgraph.py
pym/_emerge/visible.py
pym/portage/__init__.py
pym/portage/dbapi/__init__.py

index e89d30fae5f887f95ad5164771e95b811c2ac7a4..1b2f143454e7d8d9dbdc8ea904146eda1aa2b402 100644 (file)
@@ -24,9 +24,8 @@ class EbuildFetchonly(SlotObject):
                ebuild_path = portdb.findname(pkg.cpv)
                settings.setcpv(pkg)
                debug = settings.get("PORTAGE_DEBUG") == "1"
-               restrict_fetch = 'fetch' in settings['PORTAGE_RESTRICT'].split()
 
-               if restrict_fetch:
+               if 'fetch' in pkg.metadata.restrict:
                        rval = self._execute_with_builddir()
                else:
                        rval = portage.doebuild(ebuild_path, "fetch",
index c5dcd30e2c00fd97128e2288e084cb7a7483c90f..d7284ce3ae21f12f2e8815678b6779f036b31e61 100644 (file)
@@ -26,7 +26,7 @@ class Package(Task):
                "installed", "metadata", "onlydeps", "operation",
                "root_config", "type_name",
                "category", "counter", "cp", "cpv_split",
-               "inherited", "iuse", "mtime",
+               "inherited", "invalid", "iuse", "mtime",
                "pf", "pv_split", "root", "slot", "slot_atom",) + \
        ("_use",)
 
@@ -54,6 +54,11 @@ class Package(Task):
                self.cpv_split = portage.catpkgsplit(self.cpv)
                self.pv_split = self.cpv_split[1:]
 
+       def _invalid_metadata(self, msg):
+               if self.invalid is None:
+                       self.invalid = []
+               self.invalid.append(msg)
+
        class _use_class(object):
 
                __slots__ = ("__weakref__", "enabled")
@@ -69,7 +74,9 @@ class Package(Task):
 
        class _iuse(object):
 
-               __slots__ = ("__weakref__", "all", "enabled", "disabled", "iuse_implicit", "regex", "tokens")
+               __slots__ = ("__weakref__", "all", "enabled", "disabled",
+                       "iuse_implicit", "tokens") + \
+                       ('_regex',)
 
                def __init__(self, tokens, iuse_implicit):
                        self.tokens = tuple(tokens)
@@ -89,20 +96,23 @@ class Package(Task):
                        self.disabled = frozenset(disabled)
                        self.all = frozenset(chain(enabled, disabled, other))
 
-               def __getattribute__(self, name):
-                       if name == "regex":
-                               try:
-                                       return object.__getattribute__(self, "regex")
-                               except AttributeError:
-                                       all = object.__getattribute__(self, "all")
-                                       iuse_implicit = object.__getattribute__(self, "iuse_implicit")
-                                       # Escape anything except ".*" which is supposed
-                                       # to pass through from _get_implicit_iuse()
-                                       regex = (re.escape(x) for x in chain(all, iuse_implicit))
-                                       regex = "^(%s)$" % "|".join(regex)
-                                       regex = regex.replace("\\.\\*", ".*")
-                                       self.regex = re.compile(regex)
-                       return object.__getattribute__(self, name)
+               @property
+               def regex(self):
+                       """
+                       @returns: A regular expression that matches valid USE values which
+                               may be specified in USE dependencies.
+                       """
+                       try:
+                               return self._regex
+                       except AttributeError:
+                               # Escape anything except ".*" which is supposed
+                               # to pass through from _get_implicit_iuse()
+                               regex = (re.escape(x) for x in \
+                                       chain(self.all, self.iuse_implicit))
+                               regex = "^(%s)$" % "|".join(regex)
+                               regex = re.compile(regex.replace("\\.\\*", ".*"))
+                               self._regex = regex
+                               return regex
 
        def _get_hash_key(self):
                hash_key = getattr(self, "_hash_key", None)
@@ -158,6 +168,8 @@ class _PackageMetadataWrapper(_PackageMetadataWrapperBase):
        __slots__ = ("_pkg",)
        _wrapped_keys = frozenset(
                ["COUNTER", "INHERITED", "IUSE", "SLOT", "_mtime_"])
+       _use_conditional_keys = frozenset(
+               ['LICENSE', 'PROPERTIES', 'PROVIDE', 'RESTRICT',])
 
        def __init__(self, pkg, metadata):
                _PackageMetadataWrapperBase.__init__(self)
@@ -172,11 +184,17 @@ class _PackageMetadataWrapper(_PackageMetadataWrapperBase):
 
        def __getitem__(self, k):
                v = _PackageMetadataWrapperBase.__getitem__(self, k)
-               if k in ('PROVIDE', 'LICENSE',):
+               if k in self._use_conditional_keys:
                        if '?' in v:
-                               v = paren_enclose(paren_normalize(use_reduce(
-                                       paren_reduce(v), uselist=self._pkg.use.enabled)))
-                               self[k] = v
+                               try:
+                                       v = paren_enclose(paren_normalize(use_reduce(
+                                               paren_reduce(v), uselist=self._pkg.use.enabled)))
+                               except portage.exception.InvalidDependString:
+                                       # This error should already have been registered via
+                                       # self._pkg._invalid_metadata().
+                                       pass
+                               else:
+                                       self[k] = v
 
                elif k == 'USE' and not self._pkg.built:
                        if not v:
@@ -193,6 +211,11 @@ class _PackageMetadataWrapper(_PackageMetadataWrapperBase):
                _PackageMetadataWrapperBase.__setitem__(self, k, v)
                if k in self._wrapped_keys:
                        getattr(self, "_set_" + k.lower())(k, v)
+               elif k in self._use_conditional_keys:
+                       try:
+                               use_reduce(paren_reduce(v), matchall=1)
+                       except portage.exception.InvalidDependString, e:
+                               self._pkg._invalid_metadata("%s: %s" % (k, e))
 
        def _set_inherited(self, k, v):
                if isinstance(v, basestring):
@@ -221,3 +244,11 @@ class _PackageMetadataWrapper(_PackageMetadataWrapperBase):
                        except ValueError:
                                v = 0
                self._pkg.mtime = v
+
+       @property
+       def properties(self):
+               return self['PROPERTIES'].split()
+
+       @property
+       def restrict(self):
+               return self['RESTRICT'].split()
index 2279ab26c17fc8ac44c514c8b9a24da2cfb91b89..fa20b8019dca3ddae35362cf94efde9bbf2710dc 100644 (file)
@@ -330,14 +330,7 @@ class Scheduler(PollScheduler):
                        if not (isinstance(task, Package) and \
                                task.operation == "merge"):
                                continue
-                       try:
-                               properties = flatten(use_reduce(paren_reduce(
-                                       task.metadata["PROPERTIES"]), uselist=task.use.enabled))
-                       except portage.exception.InvalidDependString, e:
-                               show_invalid_depstring_notice(task,
-                                       task.metadata["PROPERTIES"], str(e))
-                               raise self._unknown_internal_error()
-                       if "interactive" in properties:
+                       if 'interactive' in task.metadata.properties:
                                interactive_tasks.append(task)
                return interactive_tasks
 
index b19dbb1b65203bf083d08345f9125b2ac4c611e8..515bac2fe1ad6c1256f6f321d5ec5e314a1c2891 100644 (file)
@@ -3711,18 +3711,8 @@ class depgraph(object):
                                else:
                                        repo_path_real = portdb.getRepositoryPath(repo_name)
                                pkg_use = list(pkg.use.enabled)
-                               try:
-                                       restrict = flatten(use_reduce(paren_reduce(
-                                               pkg.metadata["RESTRICT"]), uselist=pkg_use))
-                               except portage.exception.InvalidDependString, e:
-                                       if not pkg.installed:
-                                               show_invalid_depstring_notice(x,
-                                                       pkg.metadata["RESTRICT"], str(e))
-                                               del e
-                                               return 1
-                                       restrict = []
-                               if "ebuild" == pkg_type and x[3] != "nomerge" and \
-                                       "fetch" in restrict:
+                               if not pkg.built and pkg.operation == 'merge' and \
+                                       'fetch' in pkg.metadata.restrict:
                                        fetch = red("F")
                                        if ordered:
                                                counters.restrict_fetch += 1
@@ -4009,18 +3999,8 @@ class depgraph(object):
                                                else:
                                                        return colorize("PKG_NOMERGE", pkg_str)
 
-                               try:
-                                       properties = flatten(use_reduce(paren_reduce(
-                                               pkg.metadata["PROPERTIES"]), uselist=pkg.use.enabled))
-                               except portage.exception.InvalidDependString, e:
-                                       if not pkg.installed:
-                                               show_invalid_depstring_notice(pkg,
-                                                       pkg.metadata["PROPERTIES"], str(e))
-                                               del e
-                                               return 1
-                                       properties = []
-                               interactive = "interactive" in properties
-                               if interactive and pkg.operation == "merge":
+                               if 'interactive' in pkg.metadata.properties and \
+                                       pkg.operation == 'merge':
                                        addl = colorize("WARN", "I") + addl[1:]
                                        if ordered:
                                                counters.interactive += 1
@@ -4912,6 +4892,9 @@ def get_masking_status(pkg, pkgsettings, root_config):
                if not pkgsettings._accept_chost(pkg.cpv, pkg.metadata):
                        mreasons.append("CHOST: %s" % \
                                pkg.metadata["CHOST"])
+               if pkg.invalid:
+                       for msg in pkg.invalid:
+                               mreasons.append("invalid: %s" % (msg,))
 
        if pkg.built and not pkg.installed:
                if not "EPREFIX" in pkg.metadata or not pkg.metadata["EPREFIX"]:
index e47089ed4c02008856c46954138369ef5d06fa3e..87f5db640383c43919b058ed6d3c3f16baecaf70 100644 (file)
@@ -22,6 +22,8 @@ def visible(pkgsettings, pkg):
        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
        if pkg.built and not pkg.installed:
index 7623a58b7f0841463d235da1d485cf1b582c6be4..307574b350d5923b91ee3ef20b682be03d12982c 100644 (file)
@@ -1209,6 +1209,7 @@ class config(object):
                self.uvlist = []
                self._accept_chost_re = None
                self._accept_license = None
+               self._accept_license_str = None
 
                self.virtuals = {}
                self.virts_p = {}
@@ -2876,17 +2877,19 @@ class config(object):
                # ACCEPT_LICENSE is a lazily evaluated incremental, so that * can be
                # used to match all licenses without every having to explicitly expand
                # it to all licenses.
-               if self._accept_license is None:
-                       if self.local_config:
-                               mysplit = []
-                               for curdb in mydbs:
-                                       mysplit.extend(curdb.get('ACCEPT_LICENSE', '').split())
-                               if mysplit:
-                                       self.configlist[-1]['ACCEPT_LICENSE'] = ' '.join(mysplit)
+               if self.local_config:
+                       mysplit = []
+                       for curdb in mydbs:
+                               mysplit.extend(curdb.get('ACCEPT_LICENSE', '').split())
+                       accept_license_str = ' '.join(mysplit)
+                       if accept_license_str:
+                               self.configlist[-1]['ACCEPT_LICENSE'] = accept_license_str
+                       if accept_license_str != self._accept_license_str:
+                               self._accept_license_str = accept_license_str
                                self._accept_license = tuple(self.expandLicenseTokens(mysplit))
-                       else:
-                               # repoman will accept any license
-                               self._accept_license = ()
+               else:
+                       # repoman will accept any license
+                       self._accept_license = ()
 
                for mykey in myincrementals:
 
index db6e36fcd6a13b02858aaf84db57f8b75a2b3c64..abd6cc870d2ebf2eabe5440f727c03542617ff4f 100644 (file)
@@ -50,7 +50,7 @@ class dbapi(object):
                pass
 
        def cp_list(self, cp, use_cache=1):
-               return
+               raise NotImplementedError(self)
 
        def _cpv_sort_ascending(self, cpv_list):
                """