Esempio n. 1
0
    def add_links(self, link_type: int, *args: Any) -> None:
        link_normalizers = [
            nzs.strip, nzs.url, nzs.warn_whitespace, nzs.forbid_newlines,
            nzs.limit_length(_MAX_URL_LENGTH)
        ]

        urls = self._normalize_args(args, 'link', str, link_normalizers)

        if urls:
            self._package.links.extend((link_type, url) for url in urls)
Esempio n. 2
0
class PackageMaker(PackageMakerBase):
    _package: PackageTemplate
    _name_mapper: NameMapper
    _ident: Optional[str]
    _itemno: int
    _skipfailed: bool

    def __init__(self, logger: Logger, ident: Optional[str], itemno: int, skipfailed: bool = False) -> None:
        super(PackageMaker, self).__init__(logger)
        self._package = PackageTemplate()
        self._name_mapper = NameMapper()
        self._ident = ident
        self._itemno = itemno
        self._skipfailed = skipfailed

    def _get_ident(self) -> str:
        return self._ident or self._name_mapper.describe() or 'item #{}'.format(self._itemno)

    @_simple_setter('name', str, nzs.strip, nzs.forbid_newlines)
    def add_name(self, name: str, name_type: int) -> None:
        self._name_mapper.add_name(name, name_type)

    @_omnivorous_setter('binname', str, nzs.strip, nzs.forbid_newlines)
    def add_binnames(self, *args: Any) -> None:
        self._package.binnames.extend(args)

    @_simple_setter('version', str, nzs.strip, nzs.forbid_newlines)
    def set_version(self, version: str, version_normalizer: Optional[Callable[[str], str]] = None) -> None:
        self._package.rawversion = version
        self._package.origversion = version if version_normalizer is None else version_normalizer(version)
        self._package.version = self._package.origversion

    @_simple_setter('version', str, nzs.strip, nzs.forbid_newlines)
    def set_rawversion(self, rawversion: str) -> None:
        if rawversion != self._package.version:
            self._package.rawversion = rawversion

    @_simple_setter('arch', str, nzs.strip, nzs.forbid_newlines)
    def set_arch(self, arch: str) -> None:
        self._package.arch = arch

    @_simple_setter('subrepo', str, nzs.strip, nzs.forbid_newlines)
    def set_subrepo(self, subrepo: str) -> None:
        self._package.subrepo = subrepo

    @_simple_setter('summary', str, nzs.strip, nzs.limit_length(_MAX_SUMMARY_LENGTH))
    def set_summary(self, summary: str) -> None:
        self._package.summary = summary

    @_omnivorous_setter('maintainer', str, nzs.strip, nzs.forbid_newlines, nzs.tolower)
    def add_maintainers(self, *args: Any) -> None:
        self._package.maintainers.extend(args)

    @_omnivorous_setter('category', str, nzs.strip, nzs.forbid_newlines)
    def add_categories(self, *args: Any) -> None:
        self._package.categories.extend(args)

    @_omnivorous_setter('homepage', str, nzs.strip, nzs.url, nzs.warn_whitespace, nzs.forbid_newlines, nzs.limit_length(_MAX_URL_LENGTH))
    def add_homepages(self, *args: Any) -> None:
        self.add_links(LinkType.UPSTREAM_HOMEPAGE, args)

    @_omnivorous_setter('license', str, nzs.strip, nzs.forbid_newlines)
    def add_licenses(self, *args: Any) -> None:
        self._package.licenses.extend(args)

    @_omnivorous_setter('download', str, nzs.strip, nzs.url, nzs.warn_whitespace, nzs.forbid_newlines, nzs.limit_length(_MAX_URL_LENGTH))
    def add_downloads(self, *args: Any) -> None:
        self.add_links(LinkType.UPSTREAM_DOWNLOAD, args)

    @_omnivorous_setter('flavor', str, nzs.strip, nzs.warn_whitespace, nzs.forbid_newlines)
    def add_flavors(self, *args: Any) -> None:
        self._package.flavors.extend(args)

    def add_links(self, link_type: int, *args: Any) -> None:
        link_normalizers = [
            nzs.strip,
            nzs.url,
            nzs.warn_whitespace,
            nzs.forbid_newlines,
            nzs.limit_length(_MAX_URL_LENGTH)
        ]

        urls = self._normalize_args(args, 'link', str, link_normalizers)

        if urls:
            self._package.links.extend((link_type, url) for url in urls)

    def set_flags(self, mask: int, is_set: bool = True) -> None:
        if is_set:
            self._package.flags |= mask
        else:
            self._package.flags &= ~mask

    def set_extra_field(self, key: str, value: Any) -> None:
        self._package.extrafields[key] = value

    def add_cpe(self, vendor: Optional[str] = None, product: Optional[str] = None, edition: Optional[str] = None, lang: Optional[str] = None, sw_edition: Optional[str] = None, target_sw: Optional[str] = None, target_hw: Optional[str] = None, other: Optional[str] = None) -> None:
        self._package.cpe_vendor = vendor
        self._package.cpe_product = product
        self._package.cpe_edition = edition
        self._package.cpe_lang = lang
        self._package.cpe_sw_edition = sw_edition
        self._package.cpe_target_sw = target_sw
        self._package.cpe_target_hw = target_hw
        self._package.cpe_other = other

    def spawn(self, repo: str, family: str, subrepo: Optional[str] = None, shadow: bool = False, default_maintainer: Optional[str] = None) -> Package:
        maintainers: Optional[List[str]] = None

        if self._package.maintainers:
            maintainers = _as_opt_unique_list(self._package.maintainers)
        elif default_maintainer:
            maintainers = [default_maintainer]

        names = self._name_mapper.get_mapped_names()

        if names.name is None and names.srcname is None and names.binname is None:
            raise RuntimeError('Attempt to spawn Package without any name (name, binname, srcname) set')
        if names.trackname is None:
            raise RuntimeError('Attempt to spawn Package with unset trackname')
        if names.visiblename is None:
            raise RuntimeError('Attempt to spawn Package with unset visiblename')
        if names.projectname_seed is None:
            raise RuntimeError('Attempt to spawn Package with unset projectname_seed')
        if self._package.version is None:
            raise RuntimeError('Attempt to spawn Package with unset version')

        return Package(
            repo=repo,
            family=family,
            subrepo=self._package.subrepo or subrepo,

            name=names.name,
            srcname=names.srcname,
            binname=names.binname,
            binnames=_as_opt_unique_list(self._package.binnames),
            trackname=names.trackname,
            visiblename=names.visiblename,
            projectname_seed=names.projectname_seed,

            version=self._package.version,
            origversion=self._package.version,
            rawversion=self._package.rawversion if self._package.rawversion is not None else self._package.version,

            # XXX: arch is not used anywhere yet, and until #711 is implemented,
            # it just introduces package duplicates; it's a crude solution, but
            # just drop it here
            # arch=self._package.arch,

            maintainers=maintainers,
            category=_as_opt_first_from_list(self._package.categories),  # TODO: convert to array
            comment=self._package.summary,
            licenses=_as_opt_unique_list(self._package.licenses),

            flags=self._package.flags,
            shadow=shadow,

            extrafields=self._package.extrafields if self._package.extrafields else None,

            cpe_vendor=self._package.cpe_vendor,
            cpe_product=self._package.cpe_product,
            cpe_edition=self._package.cpe_edition,
            cpe_lang=self._package.cpe_lang,
            cpe_sw_edition=self._package.cpe_sw_edition,
            cpe_target_sw=self._package.cpe_target_sw,
            cpe_target_hw=self._package.cpe_target_hw,
            cpe_other=self._package.cpe_other,

            flavors=_as_unique_list(self._package.flavors),  # TODO: convert to string

            links=_as_opt_unique_list(self._package.links),

            # XXX: see comment for PackageStatus.UNPROCESSED
            # XXX: duplicate code: PackageTransformer does the same
            effname=names.projectname_seed,
            versionclass=PackageStatus.UNPROCESSED,
        )

    def clone(self, ident: Optional[str] = None, append_ident: Optional[str] = None) -> 'PackageMaker':
        offspring_ident = self._ident
        if ident is not None:
            offspring_ident = ident
        elif append_ident is not None:
            offspring_ident = (offspring_ident or '') + append_ident

        offspring = PackageMaker(self._logger, offspring_ident, self._itemno)
        offspring._package = deepcopy(self._package)
        offspring._name_mapper = deepcopy(self._name_mapper)

        return offspring

    def __getattr__(self, key: str) -> Any:
        return getattr(self._package, key)

    def __enter__(self) -> 'PackageMaker':
        return self

    def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> Optional[bool]:
        if exc_type:
            self.log('parsing failed ({}): {}: {}'.format(
                'skipped' if self._skipfailed else 'fatal',
                exc_type.__name__,
                exc_value
            ), severity=Logger.ERROR)

            if self._skipfailed:
                return True

        return None