def get_slot(self): slot = self.data.pop('SLOT', None) if not slot: raise metadata_errors.MetadataException( self, 'slot', 'SLOT cannot be unset or empty') if not self.eapi.valid_slot_regex.match(slot): raise metadata_errors.MetadataException( self, 'slot', f'invalid SLOT: {slot!r}') return slot
def _update_metadata(self, pkg, ebp=None): parsed_eapi = pkg.eapi if not parsed_eapi.is_supported: return {'EAPI': str(parsed_eapi)} with processor.reuse_or_request(ebp) as my_proc: try: mydata = my_proc.get_keys(pkg, self._ecache) except processor.ProcessorError as e: raise metadata_errors.MetadataException( pkg, 'data', 'failed sourcing ebuild', e) inherited = mydata.pop("INHERITED", None) # Rewrite defined_phases as needed, since we now know the EAPI. eapi = get_eapi(mydata["EAPI"]) if parsed_eapi != eapi: raise metadata_errors.MetadataException( pkg, 'eapi', f"parsed EAPI '{parsed_eapi}' doesn't match sourced EAPI '{eapi}'" ) wipes = set(mydata) wipes.difference_update(eapi.metadata_keys) if mydata["DEFINED_PHASES"] != '-': phases = mydata["DEFINED_PHASES"].split() d = eapi.phases_rev phases = set(d.get(x) for x in phases) # Discard is required should we have gotten # a phase that isn't actually in this EAPI. phases.discard(None) mydata["DEFINED_PHASES"] = ' '.join(sorted(phases)) if inherited: mydata["_eclasses_"] = self._ecache.get_eclass_data( inherited.split()) mydata['_chf_'] = chksum.LazilyHashedPath(pkg.path) for x in wipes: del mydata[x] if self._cache is not None: for cache in self._cache: if not cache.readonly: try: cache[pkg.cpvstr] = mydata except cache_errors.CacheError as e: logger.warning("caught cache error: %s", e) del e continue break return mydata
def generate_fetchables(self, allow_missing_checksums=False, ignore_unknown_mirrors=False, skip_default_mirrors=False): chksums_can_be_missing = allow_missing_checksums or \ bool(getattr(self.repo, '_allow_missing_chksums', False)) chksums_can_be_missing, chksums = self.repo._get_digests( self, allow_missing=chksums_can_be_missing) mirrors = getattr(self._parent, "mirrors", {}) if skip_default_mirrors: default_mirrors = None else: default_mirrors = getattr(self._parent, "default_mirrors", None) common = {} func = partial( create_fetchable_from_uri, self, chksums, chksums_can_be_missing, ignore_unknown_mirrors, mirrors, default_mirrors, common) # TODO: try/except block can be dropped when pkg._get_attr['fetchables'] # filtering hacks to pass custom args are fixed/removed. # # Usually dynamic_getattr_dict() catches/rethrows all exceptions as # MetadataExceptions when attrs are accessed properly (e.g. pkg.fetchables). try: d = conditionals.DepSet.parse( self.data.get("SRC_URI", ""), fetch.fetchable, operators={}, element_func=func, attr='SRC_URI', allow_src_uri_file_renames=self.eapi.options.src_uri_renames) except ebuild_errors.DepsetParseError as e: raise metadata_errors.MetadataException(self, 'fetchables', str(e)) for v in common.values(): v.uri.finalize() return d
def dynamic_getattr_dict(self, attr): functor = self._get_attr.get(attr) if functor is None: raise AttributeError(self, attr) try: val = functor(self) object.__setattr__(self, attr, val) return val except errors.MetadataException as e: if e.attr == attr: raise raise errors.MetadataException(self, attr, e.error, e.verbose) from e except (errors.PackageError, UnicodeDecodeError) as e: raise errors.MetadataException(self, attr, str(e)) from e except PermissionError as e: raise base_errors.PermissionDenied(self.path, write=False) from e
def generate_depset(c, key, non_package_type, s, **kwds): if non_package_type: return conditionals.DepSet.parse(s.data.pop(key, ""), c, operators={ "||": boolean.OrRestriction, "": boolean.AndRestriction }, **kwds) eapi_obj = s.eapi_obj if not eapi_obj.is_supported: raise metadata_errors.MetadataException( s, "eapi", "unsupported eapi: %s" % eapi_obj.magic) kwds['element_func'] = eapi_obj.atom_kls kwds['transitive_use_atoms'] = eapi_obj.options.transitive_use_atoms return conditionals.DepSet.parse(s.data.pop(key, ""), c, **kwds)
def generate_depset(kls, key, non_package_type, self, **kwds): if non_package_type: return conditionals.DepSet.parse(self.data.pop(key, ""), kls, operators={ "||": boolean.OrRestriction, "": boolean.AndRestriction }, **kwds) eapi = self.eapi if not eapi.is_supported: raise metadata_errors.MetadataException( self, "eapi", "unsupported EAPI: %s" % (eapi, )) kwds['element_func'] = eapi.atom_kls kwds['transitive_use_atoms'] = eapi.options.transitive_use_atoms return conditionals.DepSet.parse(self.data.pop(key, ""), kls, **kwds)
def get_parsed_eapi(self): ebuild = self.ebuild eapi = '0' if ebuild.path: # Use readlines directly since it does whitespace stripping # for us, far faster than native python can. i = fileutils.readlines_utf8(ebuild.path) else: i = (x.strip() for x in ebuild.text_fileobj()) for line in i: if line[0:1] in ('', '#'): continue eapi_str = _EAPI_str_regex.match(line) if eapi_str is not None: eapi_str = eapi_str.group('EAPI') if eapi_str: eapi = _EAPI_regex.match(line).group('EAPI') break try: return get_eapi(eapi) except ValueError as e: raise metadata_errors.MetadataException(self, 'eapi', f'{e}: {eapi_str!r}')
def _pkg_filter(self, raw, error_callback, pkgs): """Filter packages with bad metadata.""" while True: try: pkg = next(pkgs) except pkg_errors.PackageError as e: # ignore pkgs with invalid CPVs continue except StopIteration: return if raw: yield pkg elif self._bad_masked.has_match( pkg.versioned_atom) and error_callback is not None: error_callback(self._bad_masked[pkg.versioned_atom]) else: # check pkgs for unsupported/invalid EAPIs and bad metadata try: if not pkg.is_supported: exc = pkg_errors.MetadataException( pkg, 'eapi', f"EAPI '{pkg.eapi}' is not supported") self._bad_masked[pkg.versioned_atom] = exc if error_callback is not None: error_callback(exc) continue # TODO: add a generic metadata validation method to avoid slow metadata checks? pkg.data pkg.slot pkg.required_use except pkg_errors.MetadataException as e: self._bad_masked[e.pkg.versioned_atom] = e if error_callback is not None: error_callback(e) continue yield pkg
def _invalid_op(msg, *args): raise metadata_errors.MetadataException(self, 'eapi', f'REQUIRED_USE: {msg}')