Skip to content

Commit fc4a87f

Browse files
committed
refactor: unify Gitea build target with existing Repos type
Motivation: Maintaining multiple identical structures for repository coordinates (project, arch, product) leads to technical debt and structural duplication. Design Choices: - Replaced the short-lived BuildTarget dataclass with the established Repos NamedTuple. - Mapped project to Repos.product and product_name to Repos.version to align with existing SLFO patterns in the codebase. - Simplified add_channel_for_build_result return logic to satisfy PLR0911 while maintaining functional correctness. - Updated all call sites and tests to utilize the Repos type. User Benefits: - Reduced code duplication and structural complexity. - Improved architectural consistency across the project.
1 parent 7bba7f1 commit fc4a87f

File tree

5 files changed

+31
-39
lines changed

5 files changed

+31
-39
lines changed

openqabot/loader/gitea.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,16 @@
3030

3131
from openqabot import config
3232
from openqabot.errors import NoRepoFoundError
33-
from openqabot.types.gitea import BuildTarget, RepoConfig
33+
from openqabot.types.gitea import RepoConfig
34+
from openqabot.types.types import Repos
3435
from openqabot.utils import get_repo_url
3536
from openqabot.utils import retry10 as retried_requests
3637

3738
if TYPE_CHECKING:
3839
from collections.abc import Iterator
3940

4041
from openqabot.types.pullrequest import PullRequest
41-
from openqabot.types.types import Repos
42+
4243

4344
ARCHS = {"x86_64", "aarch64", "ppc64le", "s390x"}
4445

@@ -328,7 +329,7 @@ def get_product_version_from_repo_listing(
328329

329330

330331
def verify_repo_exists(
331-
target: BuildTarget,
332+
target: Repos,
332333
product_version: str,
333334
config: RepoConfig,
334335
) -> bool:
@@ -351,7 +352,7 @@ def verify_repo_exists(
351352

352353
def _get_product_version(
353354
res: etree._Element,
354-
target: BuildTarget,
355+
target: Repos,
355356
config: RepoConfig,
356357
) -> str:
357358
"""Extract product version from scmsync element or repository listing."""
@@ -368,26 +369,26 @@ def _get_product_version(
368369
# read product version from directory listing if the project is for a concrete product
369370
if (
370371
not product_version
371-
and target.product_name
372+
and target.version
372373
and config.obs_products
373-
and ("all" in config.obs_products or target.product_name in config.obs_products)
374+
and ("all" in config.obs_products or target.version in config.obs_products)
374375
):
375376
product_version = get_product_version_from_repo_listing(
376-
target.project, target.product_name, res.get("repository"), config.obs_download_url
377+
target.product, target.version, res.get("repository"), config.obs_download_url
377378
)
378379

379380
return product_version
380381

381382

382383
def add_channel_for_build_result(
383-
target: BuildTarget,
384+
target: Repos,
384385
res: etree._Element,
385386
projects: set[str],
386387
*,
387388
config: RepoConfig,
388389
) -> str:
389390
"""Construct a channel string for a build result and add it to the project set."""
390-
channel = f"{target.project}:{target.arch}"
391+
channel = f"{target.product}:{target.arch}"
391392
if target.arch == "local":
392393
return channel
393394

@@ -396,17 +397,16 @@ def add_channel_for_build_result(
396397
# append product version to channel if known; otherwise skip channel if this is for a concrete product
397398
if product_version:
398399
channel += f"#{product_version}"
399-
elif len(target.product_name) > 0:
400+
elif target.version:
400401
log.debug(
401402
"Channel skipped: Product version for build result %s:%s could not be determined",
402-
target.project,
403+
target.product,
403404
target.arch,
404405
)
405406
return channel
406-
if target.product_name and not verify_repo_exists(target, product_version, config):
407-
log.debug("Skipping %s:%s: repository not found for architecture %s", target.project, target.arch, target.arch)
408-
return channel
409-
projects.add(channel)
407+
408+
if not product_version or verify_repo_exists(target, product_version, config):
409+
projects.add(channel)
410410
return channel
411411

412412

@@ -445,7 +445,7 @@ def add_build_result(
445445
obs_download_url=config.settings.obs_download_url,
446446
obs_products=config.settings.obs_products_set,
447447
)
448-
target = BuildTarget(project, res.get("arch"), product)
448+
target = Repos(product=project, version=product, arch=res.get("arch"))
449449
channel = add_channel_for_build_result(target, res, results.projects, config=repo_config)
450450
if "all" not in config.settings.obs_products_set and product not in config.settings.obs_products_set:
451451
return

openqabot/types/gitea.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,6 @@
77
from dataclasses import dataclass
88

99

10-
@dataclass
11-
class BuildTarget:
12-
"""OBS build target information including project, architecture, and product name."""
13-
14-
project: str
15-
arch: str
16-
product_name: str
17-
18-
1910
@dataclass
2011
class RepoConfig:
2112
"""Configuration for OBS repository mirrors and product sets."""

openqabot/utils.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
if TYPE_CHECKING:
1919
from pathlib import Path
2020

21-
from .types.gitea import BuildTarget, RepoConfig
22-
from .types.types import Data
21+
from .types.gitea import RepoConfig
22+
from .types.types import Data, Repos
2323

2424
ANSI_ESCAPE_RE = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
2525

@@ -111,7 +111,7 @@ def merge_dicts(dict1: dict[Any, Any], dict2: dict[Any, Any]) -> dict[Any, Any]:
111111

112112

113113
def get_repo_url(
114-
target: BuildTarget,
114+
target: Repos,
115115
product_version: str,
116116
config: RepoConfig,
117117
) -> str:
@@ -120,10 +120,9 @@ def get_repo_url(
120120
if not host:
121121
return ""
122122
base = config.download_base_url.replace("%REPO_MIRROR_HOST%", host)
123-
project_path = target.project.replace(":", ":/")
123+
project_path = target.product.replace(":", ":/")
124124
return (
125-
f"{base}/{project_path}/{config.repo_type}/repo/"
126-
f"{target.product_name}-{product_version}-{target.arch}/{target.arch}/"
125+
f"{base}/{project_path}/{config.repo_type}/repo/{target.version}-{product_version}-{target.arch}/{target.arch}/"
127126
)
128127

129128

tests/test_loader_gitea_build_results.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313

1414
from openqabot.loader import gitea
1515
from openqabot.loader.gitea import BuildResults, verify_repo_exists
16-
from openqabot.types.gitea import BuildTarget, RepoConfig
16+
from openqabot.types.gitea import RepoConfig
17+
from openqabot.types.types import Repos
1718

1819
if TYPE_CHECKING:
1920
from pytest_mock import MockerFixture
@@ -149,7 +150,7 @@ def test_add_build_results_duplicate_channels(mocker: MockerFixture) -> None:
149150
mocker.patch("openqabot.loader.gitea.get_product_name", return_value="SLES")
150151

151152
def mock_add_channel(
152-
_target: BuildTarget,
153+
_target: Repos,
153154
_res: Any,
154155
projects: set[str],
155156
*,
@@ -301,7 +302,7 @@ def test_verify_repo_exists_status_codes(
301302
mock_head.return_value.ok = ok
302303

303304
result = verify_repo_exists(
304-
BuildTarget("SUSE:SLFO:1.2:PullRequest:2702:SLES", "x86_64", "SLES"),
305+
Repos("SUSE:SLFO:1.2:PullRequest:2702:SLES", "SLES", "x86_64"),
305306
"16.0",
306307
config=RepoConfig(
307308
repo_type="product",
@@ -318,7 +319,7 @@ def test_verify_repo_exists_no_product_version(mocker: MockerFixture) -> None:
318319
mock_head = mocker.patch("openqabot.loader.gitea.retried_requests.head")
319320

320321
result = verify_repo_exists(
321-
BuildTarget("SUSE:SLFO:1.2:PullRequest:2702:SLES", "x86_64", "SLES"),
322+
Repos("SUSE:SLFO:1.2:PullRequest:2702:SLES", "SLES", "x86_64"),
322323
"",
323324
config=RepoConfig(
324325
repo_type="product",
@@ -342,7 +343,7 @@ def test_verify_repo_exists_no_product_version(mocker: MockerFixture) -> None:
342343
def test_verify_repo_exists_missing_urls(download_base: str, obs_download: str) -> None:
343344
"""Verify verify_repo_exists returns True when configuration URLs are missing."""
344345
result = verify_repo_exists(
345-
BuildTarget("SUSE:SLFO:1.2:PullRequest:2702:SLES", "x86_64", "SLES"),
346+
Repos("SUSE:SLFO:1.2:PullRequest:2702:SLES", "SLES", "x86_64"),
346347
"16.0",
347348
config=RepoConfig(
348349
repo_type="product",
@@ -357,7 +358,7 @@ def test_verify_repo_exists_missing_urls(download_base: str, obs_download: str)
357358
def test_verify_repo_exists_invalid_obs_url() -> None:
358359
"""Verify verify_repo_exists returns True when obs_download_url is invalid."""
359360
result = verify_repo_exists(
360-
BuildTarget("SUSE:SLFO:1.2:PullRequest:2702:SLES", "x86_64", "SLES"),
361+
Repos("SUSE:SLFO:1.2:PullRequest:2702:SLES", "SLES", "x86_64"),
361362
"16.0",
362363
config=RepoConfig(
363364
repo_type="product",

tests/test_loader_gitea_helpers.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
from openqabot.errors import NoRepoFoundError
1414
from openqabot.loader import gitea
1515
from openqabot.types.pullrequest import PullRequest
16-
from openqabot.types.gitea import BuildTarget, RepoConfig
16+
from openqabot.types.gitea import RepoConfig
17+
from openqabot.types.types import Repos
1718

1819

1920
@pytest.fixture
@@ -149,7 +150,7 @@ def test_get_product_version_from_repo_listing_requests_json_error(
149150
def test_add_channel_for_build_result_local() -> None:
150151
projects: set[str] = set()
151152
res = gitea.add_channel_for_build_result(
152-
BuildTarget("myproj", "local", "myprod"),
153+
Repos("myproj", "myprod", "local"),
153154
None,
154155
projects,
155156
config=RepoConfig(

0 commit comments

Comments
 (0)