From b6ef0aedb1b1b7c6fd4ab2d8d38369724ec6c383 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Thu, 10 May 2012 14:23:56 -0700 Subject: Don't write or trust cache for unsupported EAPIs. 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 | 9 +++- pym/_emerge/EbuildMetadataPhase.py | 46 ++++++++++++++------ pym/_emerge/MetadataRegen.py | 6 +-- pym/_emerge/actions.py | 8 ---- pym/_emerge/depgraph.py | 2 - pym/portage/dbapi/porttree.py | 60 ++++---------------------- pym/portage/package/ebuild/getmaskingstatus.py | 2 - 7 files changed, 51 insertions(+), 82 deletions(-) diff --git a/bin/egencache b/bin/egencache index b301115f2..13860bca0 100755 --- a/bin/egencache +++ b/bin/egencache @@ -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: diff --git a/pym/_emerge/EbuildMetadataPhase.py b/pym/_emerge/EbuildMetadataPhase.py index 7f9bd3bf2..c2d3747f7 100644 --- a/pym/_emerge/EbuildMetadataPhase.py +++ b/pym/_emerge/EbuildMetadataPhase.py @@ -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) diff --git a/pym/_emerge/MetadataRegen.py b/pym/_emerge/MetadataRegen.py index 07fea73c4..79446ee79 100644 --- a/pym/_emerge/MetadataRegen.py +++ b/pym/_emerge/MetadataRegen.py @@ -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() diff --git a/pym/_emerge/actions.py b/pym/_emerge/actions.py index 62f3ff79d..eaf5a15ea 100644 --- a/pym/_emerge/actions.py +++ b/pym/_emerge/actions.py @@ -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: diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index 2df29f7ca..4d3b04c32 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -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: diff --git a/pym/portage/dbapi/porttree.py b/pym/portage/dbapi/porttree.py index 2bf17e150..f348a1529 100644 --- a/pym/portage/dbapi/porttree.py +++ b/pym/portage/dbapi/porttree.py @@ -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) diff --git a/pym/portage/package/ebuild/getmaskingstatus.py b/pym/portage/package/ebuild/getmaskingstatus.py index 66d3db528..b89fbf53b 100644 --- a/pym/portage/package/ebuild/getmaskingstatus.py +++ b/pym/portage/package/ebuild/getmaskingstatus.py @@ -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: -- cgit v1.2.3-1-g7c22