Don't write or trust cache for unsupported EAPIs.
authorZac Medico <zmedico@gentoo.org>
Thu, 10 May 2012 21:23:56 +0000 (14:23 -0700)
committerZac Medico <zmedico@gentoo.org>
Thu, 10 May 2012 23:32:39 +0000 (16:32 -0700)
Since we're supposed to be able to efficiently obtain the EAPI from
_parse_eapi_ebuild_head, we don't need to write or trust cache entries
for unsupported EAPIs.

bin/egencache
pym/_emerge/EbuildMetadataPhase.py
pym/_emerge/MetadataRegen.py
pym/_emerge/actions.py
pym/_emerge/depgraph.py
pym/portage/dbapi/porttree.py
pym/portage/package/ebuild/getmaskingstatus.py

index b301115f2a30a47d60272c0162f70ec0d6cb3e64..13860bca0a3ec00036bebe5f18a4498d1f2aac8f 100755 (executable)
@@ -238,10 +238,15 @@ class GenCache(object):
 
                self._existing_nodes = set()
 
-       def _metadata_callback(self, cpv, repo_path, metadata, ebuild_hash):
+       def _metadata_callback(self, cpv, repo_path, metadata,
+               ebuild_hash, eapi_supported):
                self._existing_nodes.add(cpv)
                self._cp_missing.discard(cpv_getkey(cpv))
-               if metadata is not None:
+
+               # Since we're supposed to be able to efficiently obtain the
+               # EAPI from _parse_eapi_ebuild_head, we don't write cache
+               # entries for unsupported EAPIs.
+               if metadata is not None and eapi_supported:
                        if metadata.get('EAPI') == '0':
                                del metadata['EAPI']
                        for trg_cache in self._trg_caches:
index 7f9bd3bf2e064a4dbaca7b585d678193729c25d9..c2d3747f7f45c060e9eb9402a3178c5d64daffb1 100644 (file)
@@ -24,8 +24,8 @@ class EbuildMetadataPhase(SubProcess):
        used to extract metadata from the ebuild.
        """
 
-       __slots__ = ("cpv", "ebuild_hash", "fd_pipes",
-               "metadata_callback", "metadata", "portdb", "repo_path", "settings") + \
+       __slots__ = ("cpv", "eapi_supported", "ebuild_hash", "fd_pipes",
+               "metadata", "portdb", "repo_path", "settings") + \
                ("_eapi", "_eapi_lineno", "_raw_metadata",)
 
        _file_names = ("ebuild",)
@@ -33,8 +33,6 @@ class EbuildMetadataPhase(SubProcess):
        _metadata_fd = 9
 
        def _start(self):
-               settings = self.settings
-               settings.setcpv(self.cpv)
                ebuild_path = self.ebuild_hash.location
 
                with io.open(_unicode_encode(ebuild_path,
@@ -54,13 +52,15 @@ class EbuildMetadataPhase(SubProcess):
                        self.wait()
                        return
 
-               if not portage.eapi_is_supported(parsed_eapi):
-                       self.metadata = self.metadata_callback(self.cpv,
-                               self.repo_path, {'EAPI' : parsed_eapi}, self.ebuild_hash)
+               self.eapi_supported = portage.eapi_is_supported(parsed_eapi)
+               if not self.eapi_supported:
+                       self.metadata = {"EAPI": parsed_eapi}
                        self._set_returncode((self.pid, os.EX_OK << 8))
                        self.wait()
                        return
 
+               settings = self.settings
+               settings.setcpv(self.cpv)
                settings.configdict['pkg']['EAPI'] = parsed_eapi
 
                debug = settings.get("PORTAGE_DEBUG") == "1"
@@ -148,28 +148,46 @@ class EbuildMetadataPhase(SubProcess):
                        metadata_lines = _unicode_decode(b''.join(self._raw_metadata),
                                encoding=_encodings['repo.content'],
                                errors='replace').splitlines()
+                       metadata_valid = True
                        if len(portage.auxdbkeys) != len(metadata_lines):
                                # Don't trust bash's returncode if the
                                # number of lines is incorrect.
-                               self.returncode = 1
+                               metadata_valid = False
                        else:
-                               metadata_valid = True
                                metadata = dict(zip(portage.auxdbkeys, metadata_lines))
                                parsed_eapi = self._eapi
                                if parsed_eapi is None:
                                        parsed_eapi = "0"
-                               if (not metadata["EAPI"] or
-                                       portage.eapi_is_supported(metadata["EAPI"])) and \
+                               self.eapi_supported = \
+                                       portage.eapi_is_supported(metadata["EAPI"])
+                               if (not metadata["EAPI"] or self.eapi_supported) and \
                                        metadata["EAPI"] != parsed_eapi:
                                        self._eapi_invalid(metadata)
                                        if 'parse-eapi-ebuild-head' in self.settings.features:
                                                metadata_valid = False
 
-                               if metadata_valid:
-                                       self.metadata = self.metadata_callback(self.cpv,
+                       if metadata_valid:
+                               # Since we're supposed to be able to efficiently obtain the
+                               # EAPI from _parse_eapi_ebuild_head, we don't write cache
+                               # entries for unsupported EAPIs.
+                               if self.eapi_supported:
+
+                                       if metadata.get("INHERITED", False):
+                                               metadata["_eclasses_"] = \
+                                                       self.portdb.repositories.get_repo_for_location(
+                                                       self.repo_path).eclass_db.get_eclass_data(
+                                                       metadata["INHERITED"].split())
+                                       else:
+                                               metadata["_eclasses_"] = {}
+                                       metadata.pop("INHERITED", None)
+
+                                       self.portdb._write_cache(self.cpv,
                                                self.repo_path, metadata, self.ebuild_hash)
                                else:
-                                       self.returncode = 1
+                                       metadata = {"EAPI": metadata["EAPI"]}
+                               self.metadata = metadata
+                       else:
+                               self.returncode = 1
 
        def _eapi_invalid(self, metadata):
                repo_name = self.portdb.getRepositoryName(self.repo_path)
index 07fea73c4996be6cebe2dad0d013acec146f35ed..79446ee799aa440945edaee20ed4a190cf43a14b 100644 (file)
@@ -78,12 +78,11 @@ class MetadataRegen(PollScheduler):
                                                cpv, ebuild_path, repo_path)
                                        if metadata is not None:
                                                if consumer is not None:
-                                                       consumer(cpv, repo_path, metadata, ebuild_hash)
+                                                       consumer(cpv, repo_path, metadata, ebuild_hash, True)
                                                continue
 
                                        yield EbuildMetadataPhase(cpv=cpv,
                                                ebuild_hash=ebuild_hash,
-                                               metadata_callback=portdb._metadata_callback,
                                                portdb=portdb, repo_path=repo_path,
                                                settings=portdb.doebuild_settings)
 
@@ -177,7 +176,8 @@ class MetadataRegen(PollScheduler):
                        self._consumer(metadata_process.cpv,
                                metadata_process.repo_path,
                                metadata_process.metadata,
-                               metadata_process.ebuild_hash)
+                               metadata_process.ebuild_hash,
+                               metadata_process.eapi_supported)
 
                self._schedule()
 
index 62f3ff79d1f7d639a771e012e5cba132b9cf1d53..eaf5a15ea2382e9ad6b88eec2a4a2dab5dd5b3b6 100644 (file)
@@ -1752,7 +1752,6 @@ def action_metadata(settings, portdb, myopts, porttrees=None):
                                eapi = src.get('EAPI')
                                if not eapi:
                                        eapi = '0'
-                               eapi = eapi.lstrip('-')
                                eapi_supported = eapi_is_supported(eapi)
                                if not eapi_supported:
                                        continue
@@ -1800,13 +1799,6 @@ def action_metadata(settings, portdb, myopts, porttrees=None):
                                        # so there's no need to overwrite it.
                                        continue
 
-                               if not eapi_supported:
-                                       src = {
-                                               'EAPI'       : '-' + eapi,
-                                               dest_chf_key : src[dest_chf_key],
-                                               '_eclasses_' : src['_eclasses_'],
-                                       }
-
                                try:
                                        tree_data.dest_db[cpv] = src
                                except CacheError:
index 2df29f7ca3ec95941ceebc0e944b6e071d5f2f11..4d3b04c32f72367fe8045df58d81ffe66459ec18 100644 (file)
@@ -7130,8 +7130,6 @@ def get_mask_info(root_config, cpv, pkgsettings,
                mreasons = ["corruption"]
        else:
                eapi = metadata['EAPI']
-               if eapi[:1] == '-':
-                       eapi = eapi[1:]
                if not portage.eapi_is_supported(eapi):
                        mreasons = ['EAPI %s' % eapi]
                else:
index 2bf17e150526a6114f52a2c28e40fd7c1bc20b7d..f348a15295d70e5d01b88e07e87b2c8a2c0d58c1 100644 (file)
@@ -95,6 +95,7 @@ class portdbapi(dbapi):
                # this purpose because doebuild makes many changes to the config
                # instance that is passed in.
                self.doebuild_settings = config(clone=self.settings)
+               self._scheduler = PollScheduler().sched_iface
                self.depcachedir = os.path.realpath(self.settings.depcachedir)
                
                if os.environ.get("SANDBOX_ON") == "1":
@@ -324,34 +325,7 @@ class portdbapi(dbapi):
                                return (filename, x)
                return (None, 0)
 
-       def _metadata_process(self, cpv, ebuild_path, repo_path):
-               """
-               Create an EbuildMetadataPhase instance to generate metadata for the
-               give ebuild.
-               @rtype: EbuildMetadataPhase
-               @return: A new EbuildMetadataPhase instance, or None if the
-                       metadata cache is already valid.
-               """
-               metadata, ebuild_hash = self._pull_valid_cache(cpv, ebuild_path, repo_path)
-               if metadata is not None:
-                       return None
-
-               process = EbuildMetadataPhase(cpv=cpv,
-                       ebuild_hash=ebuild_hash, metadata_callback=self._metadata_callback,
-                       portdb=self, repo_path=repo_path, settings=self.doebuild_settings)
-               return process
-
-       def _metadata_callback(self, cpv, repo_path, metadata, ebuild_hash):
-
-               i = metadata
-               if hasattr(metadata, "items"):
-                       i = iter(metadata.items())
-               metadata = dict(i)
-
-               if metadata.get("INHERITED", False):
-                       metadata["_eclasses_"] = self.repositories.get_repo_for_location(repo_path).eclass_db.get_eclass_data(metadata["INHERITED"].split())
-               else:
-                       metadata["_eclasses_"] = {}
+       def _write_cache(self, cpv, repo_path, metadata, ebuild_hash):
 
                try:
                        cache = self.auxdb[repo_path]
@@ -363,20 +337,6 @@ class portdbapi(dbapi):
                        traceback.print_exc()
                        cache = None
 
-               metadata.pop("INHERITED", None)
-
-               eapi = metadata.get("EAPI")
-               if not eapi or not eapi.strip():
-                       eapi = "0"
-                       metadata["EAPI"] = eapi
-               if not eapi_is_supported(eapi):
-                       keys = set(metadata)
-                       keys.discard('_eclasses_')
-                       keys.discard('_mtime_')
-                       keys.discard('_%s_' % chf)
-                       metadata.update((k, '') for k in keys)
-                       metadata["EAPI"] = "-" + eapi.lstrip("-")
-
                if cache is not None:
                        try:
                                cache[cpv] = metadata
@@ -384,7 +344,6 @@ class portdbapi(dbapi):
                                # Normally this shouldn't happen, so we'll show
                                # a traceback for debugging purposes.
                                traceback.print_exc()
-               return metadata
 
        def _pull_valid_cache(self, cpv, ebuild_path, repo_path):
                try:
@@ -427,7 +386,10 @@ class portdbapi(dbapi):
                        if not eapi:
                                eapi = '0'
                                metadata['EAPI'] = eapi
-                       if eapi[:1] == '-' and eapi_is_supported(eapi[1:]):
+                       if not eapi_is_supported(eapi):
+                               # Since we're supposed to be able to efficiently obtain the
+                               # EAPI from _parse_eapi_ebuild_head, we disregard cache entries
+                               # for unsupported EAPIs.
                                continue
                        if auxdb.validate_entry(metadata, ebuild_hash, eclass_db):
                                break
@@ -482,13 +444,9 @@ class portdbapi(dbapi):
                        if myebuild in self._broken_ebuilds:
                                raise KeyError(mycpv)
 
-                       self.doebuild_settings.setcpv(mycpv)
-
                        proc = EbuildMetadataPhase(cpv=mycpv,
-                               ebuild_hash=ebuild_hash,
-                               metadata_callback=self._metadata_callback, portdb=self,
-                               repo_path=mylocation,
-                               scheduler=PollScheduler().sched_iface,
+                               ebuild_hash=ebuild_hash, portdb=self,
+                               repo_path=mylocation, scheduler=self._scheduler,
                                settings=self.doebuild_settings)
 
                        proc.start()
@@ -552,7 +510,7 @@ class portdbapi(dbapi):
                        # since callers already handle it.
                        raise portage.exception.InvalidDependString(
                                "getFetchMap(): '%s' has unsupported EAPI: '%s'" % \
-                               (mypkg, eapi.lstrip("-")))
+                               (mypkg, eapi))
 
                return _parse_uri_map(mypkg, {'EAPI':eapi,'SRC_URI':myuris},
                        use=useflags)
index 66d3db528a8768edb96603bc176448eaae0b5457..b89fbf53b8d2ad90c0c935beae895d366cf41188 100644 (file)
@@ -79,8 +79,6 @@ def _getmaskingstatus(mycpv, settings, portdb, myrepo=None):
        mygroups = settings._getKeywords(mycpv, metadata)
        licenses = metadata["LICENSE"]
        properties = metadata["PROPERTIES"]
-       if eapi.startswith("-"):
-               eapi = eapi[1:]
        if not eapi_is_supported(eapi):
                return [_MaskReason("EAPI", "EAPI %s" % eapi)]
        elif _eapi_is_deprecated(eapi) and not installed: