Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
c39af8a
refactor copr repo provider to facilitate listing packages
AthreyVinay Mar 19, 2026
cf01d3b
refactor copr repo provider to fetch .repo file via api
AthreyVinay Mar 13, 2026
9412400
refactor: move COPR utilities to the sharred module
AthreyVinay Mar 16, 2026
f2dbad5
rebasing...
AthreyVinay Mar 20, 2026
98a3be1
more rebasing...
AthreyVinay Mar 20, 2026
e26d1f7
address comments...
AthreyVinay Mar 20, 2026
cbc3ff4
address comments...
AthreyVinay Mar 24, 2026
4cc6c09
address comments...
AthreyVinay Mar 30, 2026
39949af
(probable)fix: failing tests...
AthreyVinay Mar 30, 2026
b79e159
rebasing/conflicts...
AthreyVinay Mar 30, 2026
46d9854
refactor copr repo provider to facilitate listing packages
AthreyVinay Mar 19, 2026
939f34a
refactor copr repo provider to fetch .repo file via api
AthreyVinay Mar 13, 2026
d536606
refactor: move COPR utilities to the sharred module
AthreyVinay Mar 16, 2026
f9ab548
rebasing...
AthreyVinay Mar 20, 2026
374e1f6
more rebasing...
AthreyVinay Mar 20, 2026
ae5e5b5
address comments...
AthreyVinay Mar 24, 2026
c6826ba
refactor copr repo provider to facilitate listing packages
AthreyVinay Mar 19, 2026
532ece0
refactor copr repo provider to fetch .repo file via api
AthreyVinay Mar 13, 2026
74427cc
refactor: move COPR utilities to the sharred module
AthreyVinay Mar 16, 2026
d5b0c23
more rebasing...
AthreyVinay Mar 20, 2026
609d50d
address comments...
AthreyVinay Mar 24, 2026
c0f0773
refactor copr repo provider to facilitate listing packages
AthreyVinay Mar 19, 2026
a8652d2
refactor copr repo provider to fetch .repo file via api
AthreyVinay Mar 13, 2026
c93f84f
refactor: move COPR utilities to the sharred module
AthreyVinay Mar 16, 2026
bfdb943
more rebasing...
AthreyVinay Mar 20, 2026
0926e2b
address comments...
AthreyVinay Mar 24, 2026
b0b46ff
persist repository metadata in artifacts.yaml
AthreyVinay Mar 16, 2026
a3508c5
refactor: return type of list_packages
AthreyVinay Mar 23, 2026
d9db859
refactor: return type of list_packages
AthreyVinay Mar 30, 2026
cbeec45
address comments...
AthreyVinay Mar 31, 2026
129205d
Drop unused import
psss Apr 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions tests/unit/artifact/test_copr_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import pytest

from tmt.package_managers._rpm import RpmVersion


@pytest.mark.parametrize(
("raw_id", "expected"),
Expand Down Expand Up @@ -68,8 +70,8 @@ def test_enumerate_artifacts(
mock_guest.package_manager = mock_package_manager

mock_package_manager.list_packages.return_value = [
'tmt-1.69.0-1.fc42.noarch',
'tmt-all-0:1.69.0-1.fc42.noarch',
RpmVersion.from_nevra('tmt-1.69.0-1.fc42.noarch'),
RpmVersion.from_nevra('tmt-all-0:1.69.0-1.fc42.noarch'),
]

provider = artifact_provider("copr.repository:@teemtee/stable")
Expand Down
13 changes: 3 additions & 10 deletions tmt/package_managers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,21 +499,14 @@ def install_repository(self, repository: "Repository") -> CommandOutput:
"""
return self.guest.execute(self.engine.install_repository(repository))

def list_packages(self, repository: "Repository") -> list[str]:
def list_packages(self, repository: "Repository") -> list[Version]:
"""
List packages available in the specified repository.

:param repository: The repository to query.
:returns: A list of package names available in the repository.
:returns: A list of versions available in the repository.
"""
script = self.engine.list_packages(repository)
output = self.guest.execute(script)
stdout = output.stdout

if stdout is None:
raise GeneralError("Repository query provided no output")

return stdout.strip().splitlines()
raise NotImplementedError

def get_package_origin(self, packages: Iterable[str]) -> 'dict[str, PackageOrigin]':
"""
Expand Down
14 changes: 14 additions & 0 deletions tmt/package_managers/dnf.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
PackageManager,
PackageManagerEngine,
Repository,
Version,
escape_installables,
provides_package_manager,
)
Expand Down Expand Up @@ -242,6 +243,19 @@ class Dnf(PackageManager[DnfEngine]):
# the `dnf` family just stays below it.
probe_priority = 50

def list_packages(self, repository: Repository) -> list[Version]:
from tmt.package_managers._rpm import RpmVersion

script = self.engine.list_packages(repository)
output = self.guest.execute(script)
stdout = output.stdout

if stdout is None:
raise GeneralError("Repository query provided no output")

stripped_lines = (line.strip() for line in stdout.strip().splitlines())
return [RpmVersion.from_nevra(line) for line in stripped_lines if line]

def check_presence(self, *installables: Installable) -> dict[Installable, bool]:
try:
output = self.guest.execute(self.engine.check_presence(*installables))
Expand Down
39 changes: 13 additions & 26 deletions tmt/steps/prepare/artifact/providers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
from tmt.container import container
from tmt.guest import Guest
from tmt.package_managers import Repository, Version
from tmt.package_managers._rpm import RpmVersion
from tmt.plugins import PluginRegistry
from tmt.utils import Path, ShellScript

Expand Down Expand Up @@ -110,7 +109,7 @@ def __init__(self, raw_id: str, repository_priority: int, logger: tmt.log.Logger
self.sanitized_id = tmt.utils.sanitize_name(raw_id, allow_slash=False)

self.id = self._extract_provider_id(raw_id)
self._artifacts = []
self._artifacts: list[ArtifactInfo] = []

@classmethod
@abstractmethod
Expand Down Expand Up @@ -229,9 +228,7 @@ def get_repositories(self) -> list['Repository']:
"""
return []

def enumerate_artifacts(
self, guest: Guest
) -> None: # TODO: refactor this once the NEVRA parsing is centralized.
def enumerate_artifacts(self, guest: Guest) -> None:
"""
Enumerate artifacts from repositories returned by :py:meth:`get_repositories`
and populate :py:attr:`_artifacts`. Call this after repositories are installed.
Expand All @@ -241,35 +238,25 @@ def enumerate_artifacts(
"""
for repository in self.get_repositories():
try:
nevras = guest.package_manager.list_packages(repository)
packages = guest.package_manager.list_packages(repository)
except tmt.utils.RunError as error:
tmt.utils.show_exception_as_warning(
exception=error,
message=f"Failed to enumerate packages from repository '{repository.name}'.",
logger=self.logger,
)
continue
count = 0
for nevra in nevras:
nevra = nevra.strip()
if not nevra:
continue
try:
self._artifacts.append(
ArtifactInfo(
version=RpmVersion.from_nevra(nevra),
provider=self,
location=repository.name,
)
for rpm_version in packages:
self._artifacts.append(
ArtifactInfo(
version=rpm_version,
provider=self,
location=repository.name,
)
count += 1
except ValueError as error:
tmt.utils.show_exception_as_warning(
exception=error,
message=f"Could not parse NEVRA '{nevra}'.",
logger=self.logger,
)
self.logger.debug(f"Enumerated {count} packages from repository '{repository.name}'.")
)
self.logger.debug(
f"Enumerated {len(packages)} packages from repository '{repository.name}'."
)

# B027: "... is an empty method in an abstract base class, but has
# no abstract decorator" - expected, it's a default implementation
Expand Down
Loading