Exemplo n.º 1
0
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
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
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
Exemplo n.º 4
0
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
Exemplo n.º 5
0
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)
Exemplo n.º 6
0
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)
Exemplo n.º 7
0
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}')
Exemplo n.º 8
0
    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
Exemplo n.º 9
0
 def _invalid_op(msg, *args):
     raise metadata_errors.MetadataException(self, 'eapi', f'REQUIRED_USE: {msg}')