fix: support zstd-compressed repodata in packages.json generator

createrepo_c on Fedora 43 uses zstd compression by default. Detect
the file extension and use zstdcat for .zst files, gzip for .gz.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-27 13:30:52 +03:00
parent de96e7c687
commit 10263e4a2b

View File

@@ -5,6 +5,7 @@ import argparse
import gzip import gzip
import json import json
import os import os
import subprocess
import sys import sys
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from datetime import datetime, timezone from datetime import datetime, timezone
@@ -30,15 +31,27 @@ def find_repodata_file(repodata_dir, data_type):
return None return None
def open_compressed(path):
"""Open a gzip or zstd compressed file for reading."""
if path.endswith(".zst"):
result = subprocess.run(
["zstdcat", path], capture_output=True, check=True
)
import io
return io.BytesIO(result.stdout)
else:
return gzip.open(path, "rb")
def parse_primary(repodata_dir): def parse_primary(repodata_dir):
"""Parse primary.xml.gz and return package metadata.""" """Parse primary.xml.{gz,zst} and return package metadata."""
path = find_repodata_file(repodata_dir, "primary") path = find_repodata_file(repodata_dir, "primary")
if not path: if not path:
print("error: primary metadata not found in repomd.xml", file=sys.stderr) print("error: primary metadata not found in repomd.xml", file=sys.stderr)
sys.exit(1) sys.exit(1)
packages = {} packages = {}
with gzip.open(path, "rb") as f: with open_compressed(path) as f:
tree = ET.parse(f) tree = ET.parse(f)
for pkg in tree.getroot().findall(f"{{{RPM_NS}}}package"): for pkg in tree.getroot().findall(f"{{{RPM_NS}}}package"):
@@ -82,7 +95,7 @@ def parse_other(repodata_dir, packages):
if not path: if not path:
return return
with gzip.open(path, "rb") as f: with open_compressed(path) as f:
tree = ET.parse(f) tree = ET.parse(f)
for pkg in tree.getroot().findall(f"{{{OTHER_NS}}}package"): for pkg in tree.getroot().findall(f"{{{OTHER_NS}}}package"):