Skip to content

Commit fe6537b

Browse files
committed
Refactor: Extract source RPM mapping into common function
Extract duplicated source RPM mapping logic from v1 endpoint and generate_updateinfo_xml() into a shared build_source_rpm_mapping() function. This refactoring: - Eliminates code duplication between v1 and v2 endpoints - Centralizes the logic for finding source RPMs for packages - Includes fix for module packages where package_name has 'module.' prefix - Makes future improvements easier to apply consistently The fix handles the case where: - Binary packages have package_name = 'delve' - Source packages have package_name = 'module.delve' - Strip 'module.' prefix for proper matching
1 parent 1c8d660 commit fe6537b

File tree

1 file changed

+65
-54
lines changed

1 file changed

+65
-54
lines changed

apollo/server/routes/api_updateinfo.py

Lines changed: 65 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,67 @@
2424
}
2525

2626

27+
def build_source_rpm_mapping(packages):
28+
"""
29+
Build a mapping from package names to their source RPM filenames.
30+
31+
This function handles both regular packages and module packages, where
32+
module source packages have a "module." prefix that needs to be stripped
33+
for matching with binary packages.
34+
35+
Args:
36+
packages: List of advisory package objects with package_name, module_name,
37+
module_stream, and nevra attributes
38+
39+
Returns:
40+
dict: Mapping of package names (with module prefix if applicable) to
41+
source RPM filenames. For example:
42+
{
43+
"xorg-x11-server": "xorg-x11-server-1.20.11-27.el8_10.src.rpm",
44+
"go-toolset:delve:1.24": "delve-1.24.1-1.module+el8.10.0+1987+42f155bb.src.rpm"
45+
}
46+
"""
47+
# First, create a map of package names to their package objects
48+
pkg_name_map = {}
49+
for pkg in packages:
50+
name = pkg.package_name
51+
if pkg.module_name:
52+
name = f"{pkg.module_name}:{pkg.package_name}:{pkg.module_stream}"
53+
if name not in pkg_name_map:
54+
pkg_name_map[name] = []
55+
pkg_name_map[name].append(pkg)
56+
57+
# Build the source RPM mapping
58+
pkg_src_rpm = {}
59+
for top_pkg in packages:
60+
name = top_pkg.package_name
61+
if top_pkg.module_name:
62+
name = f"{top_pkg.module_name}:{top_pkg.package_name}:{top_pkg.module_stream}"
63+
64+
if name not in pkg_src_rpm:
65+
for pkg in pkg_name_map[name]:
66+
nvra_no_epoch = EPOCH_RE.sub("", pkg.nevra)
67+
nvra = NVRA_RE.search(nvra_no_epoch)
68+
if nvra:
69+
nvr_name = nvra.group(1)
70+
nvr_arch = nvra.group(4)
71+
72+
# FIX: Handle module packages where package_name has "module." prefix
73+
# Binary packages: package_name = "delve"
74+
# Source packages: package_name = "module.delve"
75+
# We need to strip the prefix for comparison
76+
pkg_name_to_match = pkg.package_name.removeprefix("module.")
77+
78+
if pkg_name_to_match == nvr_name and nvr_arch == "src":
79+
src_rpm = nvra_no_epoch
80+
if not src_rpm.endswith(".rpm"):
81+
src_rpm += ".rpm"
82+
pkg_src_rpm[name] = src_rpm
83+
break # Found the source RPM, no need to continue
84+
85+
return pkg_src_rpm
86+
87+
2788
def resolve_product_slug(slug: str) -> Optional[str]:
2889
"""
2990
Convert product slug to supported_product.name.
@@ -190,33 +251,8 @@ async def get_updateinfo(
190251
"-debugsource-common",
191252
]
192253

193-
pkg_name_map = {}
194-
for pkg in advisory.packages:
195-
name = pkg.package_name
196-
if pkg.module_name:
197-
name = f"{pkg.module_name}:{pkg.package_name}:{pkg.module_stream}"
198-
if name not in pkg_name_map:
199-
pkg_name_map[name] = []
200-
201-
pkg_name_map[name].append(pkg)
202-
203-
pkg_src_rpm = {}
204-
for top_pkg in advisory.packages:
205-
name = top_pkg.package_name
206-
if top_pkg.module_name:
207-
name = f"{top_pkg.module_name}:{top_pkg.package_name}:{top_pkg.module_stream}"
208-
if name not in pkg_src_rpm:
209-
for pkg in pkg_name_map[name]:
210-
nvra_no_epoch = EPOCH_RE.sub("", pkg.nevra)
211-
nvra = NVRA_RE.search(nvra_no_epoch)
212-
if nvra:
213-
nvr_name = nvra.group(1)
214-
nvr_arch = nvra.group(4)
215-
if pkg.package_name == nvr_name and nvr_arch == "src":
216-
src_rpm = nvra_no_epoch
217-
if not src_rpm.endswith(".rpm"):
218-
src_rpm += ".rpm"
219-
pkg_src_rpm[name] = src_rpm
254+
# Build source RPM mapping using common function
255+
pkg_src_rpm = build_source_rpm_mapping(advisory.packages)
220256

221257
# Collection list, may be more than one if module RPMs are involved
222258
collections = {}
@@ -500,33 +536,8 @@ def generate_updateinfo_xml(
500536
"-debugsource-common",
501537
]
502538

503-
pkg_name_map = {}
504-
for pkg in advisory.packages:
505-
name = pkg.package_name
506-
if pkg.module_name:
507-
name = f"{pkg.module_name}:{pkg.package_name}:{pkg.module_stream}"
508-
if name not in pkg_name_map:
509-
pkg_name_map[name] = []
510-
511-
pkg_name_map[name].append(pkg)
512-
513-
pkg_src_rpm = {}
514-
for top_pkg in advisory.packages:
515-
name = top_pkg.package_name
516-
if top_pkg.module_name:
517-
name = f"{top_pkg.module_name}:{top_pkg.package_name}:{top_pkg.module_stream}"
518-
if name not in pkg_src_rpm:
519-
for pkg in pkg_name_map[name]:
520-
nvra_no_epoch = EPOCH_RE.sub("", pkg.nevra)
521-
nvra = NVRA_RE.search(nvra_no_epoch)
522-
if nvra:
523-
nvr_name = nvra.group(1)
524-
nvr_arch = nvra.group(4)
525-
if pkg.package_name == nvr_name and nvr_arch == "src":
526-
src_rpm = nvra_no_epoch
527-
if not src_rpm.endswith(".rpm"):
528-
src_rpm += ".rpm"
529-
pkg_src_rpm[name] = src_rpm
539+
# Build source RPM mapping using common function
540+
pkg_src_rpm = build_source_rpm_mapping(advisory.packages)
530541

531542
# Determine the product name to use for package filtering
532543
filter_product_name = product_name_for_packages

0 commit comments

Comments
 (0)