Skip to content

Commit

Permalink
pkg: Support upstream metadata
Browse files Browse the repository at this point in the history
Fully supported only for Portage, pkgcore can return only remote-ids.
  • Loading branch information
CyberTailor committed Apr 20, 2024
1 parent 3cc8b2b commit 72d1576
Show file tree
Hide file tree
Showing 6 changed files with 381 additions and 12 deletions.
9 changes: 9 additions & 0 deletions gentoopm/basepm/pkg.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# (c) 2011-2024 Michał Górny <[email protected]>
# (c) 2024 Anna <[email protected]>
# SPDX-License-Identifier: GPL-2.0-or-later

import os.path
Expand All @@ -14,6 +15,7 @@

from .atom import PMAtom, PMPackageKey
from .environ import PMPackageEnvironment
from gentoopm.basepm.upstream import PMUpstream

PMPackageState = EnumTuple("PMPackageState", "installable", "installed")

Expand Down Expand Up @@ -417,6 +419,13 @@ def maintainers(self):
"""
pass

@property
@abstractmethod
def upstream(self) -> PMUpstream:
"""
Get the package upstream metadata.
"""

@abstractproperty
def repo_masked(self):
"""
Expand Down
190 changes: 190 additions & 0 deletions gentoopm/basepm/upstream.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
# (c) 2024 Anna <[email protected]>
# SPDX-License-Identifier: GPL-2.0-or-later

import typing
from abc import abstractmethod
from collections.abc import Sequence
from enum import Enum

from ..util import (
ABCObject,
StringCompat
)


class PMUpstreamMaintainerStatus(Enum):
"""
Maintainer status enumeration.
"""

UNKNOWN = None
ACTIVE = "active"
INACTIVE = "inactive"


class PMUpstreamMaintainer(ABCObject, StringCompat):
"""
A base class for an upstream maintainer.
"""

_name: str
_email: typing.Optional[str]
_status: PMUpstreamMaintainerStatus

def __new__(cls, name: str, email: typing.Optional[str] = None,
status: PMUpstreamMaintainerStatus = PMUpstreamMaintainerStatus.UNKNOWN):
"""
Instantiate the actual string. Requires other props prepared
beforehand.
@param email: maintainer's e-mail address
@param name: maintainer's name
@param status: maintainer's activity status
"""

parts = [name]
if email is not None:
parts.append(f"<{email}>")

ret = StringCompat.__new__(cls, " ".join(parts))
ret._name = name
ret._email = email
ret._status = status
return ret

@property
def name(self) -> str:
"""
Maintainer's name.
"""
return self._name

@property
def email(self) -> typing.Optional[str]:
"""
Maintainer's e-mail address.
"""
return self._email

@property
def status(self) -> PMUpstreamMaintainerStatus:
"""
Maintainer's activity status.
"""
return self._status


class PMUpstreamDoc(ABCObject, StringCompat):
"""
A base class for a link to the upstream documentation.
"""

_url: str
_lang: str

def __new__(cls, url: str, lang: str = "en"):
"""
Instantiate the actual string. Requires other props prepared
beforehand.
@param url: documentation URL
@param lang: documentation language
"""

ret = StringCompat.__new__(cls, url)
ret._url = url
ret._lang = lang
return ret

@property
def url(self) -> str:
"""
Documentation URL.
"""
return self._url

@property
def lang(self) -> str:
"""
Documentation language.
"""
return self._lang


class PMUpstreamRemoteID(ABCObject, StringCompat):
"""
A base class for an upstream remote-id.
"""

_name: str
_site: str

def __new__(cls, name: str, site: str):
"""
Instantiate the actual string. Requires other props prepared
beforehand.
@param name: package's identifier on the site
@param site: type of package identification tracker
"""

ret = StringCompat.__new__(cls, f"{site}: {name}")
ret._name = name
ret._site = site
return ret

@property
def name(self) -> str:
"""
Package's identifier on the site.
"""
return self._name

@property
def site(self) -> str:
"""
Type of package identification tracker.
"""
return self._site


class PMUpstream(ABCObject):
"""
An abstract class representing upstream metadata.
"""

@property
def bugs_to(self) -> typing.Optional[str]:
"""
Location where to report bugs (may also be an email address prefixed
with "mailto:").
"""
raise NotImplementedError

@property
def changelog(self) -> typing.Optional[str]:
"""
URL where the upstream changelog can be found.
"""
raise NotImplementedError

@property
def docs(self) -> Sequence[PMUpstreamDoc]:
"""
URLs where the location of the upstream documentation can be found.
"""
raise NotImplementedError

@property
def maintainers(self) -> Sequence[PMUpstreamMaintainer]:
"""
Upstream maintainers.
"""
raise NotImplementedError

@property
@abstractmethod
def remote_ids(self) -> Sequence[PMUpstreamRemoteID]:
"""
Package's identifiers on third-party trackers.
"""
27 changes: 27 additions & 0 deletions gentoopm/pkgcorepm/pkg.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# (c) 2011-2024 Michał Górny <[email protected]>
# (c) 2024 Anna <[email protected]>
# SPDX-License-Identifier: GPL-2.0-or-later

from collections.abc import Iterable, Sequence

from pkgcore.ebuild.repo_objs import Upstream

from ..basepm.pkg import (
PMPackage,
PMPackageDescription,
Expand All @@ -12,6 +17,10 @@
PMPackageMaintainer,
)
from ..basepm.pkgset import PMPackageSet, PMFilteredPackageSet
from gentoopm.basepm.upstream import (
PMUpstream,
PMUpstreamRemoteID,
)
from ..util import SpaceSepTuple, SpaceSepFrozenSet

from .atom import PkgCoreAtom, PkgCorePackageKey
Expand Down Expand Up @@ -168,6 +177,20 @@ def __str__(self):
return "=%s" % s


class PkgCoreUpstreamRemoteID(PMUpstreamRemoteID):
def __new__(cls, remote_id: Upstream):
return PMUpstreamRemoteID.__new__(cls, remote_id.name, remote_id.type)


class PkgCoreUpstream(PMUpstream):
def __init__(self, remote_ids: Iterable[Upstream]):
self._remote_ids = remote_ids

@property
def remote_ids(self) -> Sequence[PkgCoreUpstreamRemoteID]:
return tuple(PkgCoreUpstreamRemoteID(r) for r in self._remote_ids)


class PkgCoreInstallablePackage(PkgCorePackage, PMInstallablePackage):
@property
def inherits(self):
Expand Down Expand Up @@ -228,6 +251,10 @@ def restrict(self):
def maintainers(self):
return PkgCoreMaintainerTuple(self._pkg.maintainers)

@property
def upstream(self) -> PkgCoreUpstream:
return PkgCoreUpstream(self._pkg.upstreams)

@property
def repo_masked(self):
for m in self._pkg.repo.masked:
Expand Down
Loading

0 comments on commit 72d1576

Please sign in to comment.