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 json
import os
import subprocess
import sys
import xml.etree.ElementTree as ET
from datetime import datetime, timezone
@@ -30,15 +31,27 @@ def find_repodata_file(repodata_dir, data_type):
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):
"""Parse primary.xml.gz and return package metadata."""
"""Parse primary.xml.{gz,zst} and return package metadata."""
path = find_repodata_file(repodata_dir, "primary")
if not path:
print("error: primary metadata not found in repomd.xml", file=sys.stderr)
sys.exit(1)
packages = {}
with gzip.open(path, "rb") as f:
with open_compressed(path) as f:
tree = ET.parse(f)
for pkg in tree.getroot().findall(f"{{{RPM_NS}}}package"):
@@ -82,7 +95,7 @@ def parse_other(repodata_dir, packages):
if not path:
return
with gzip.open(path, "rb") as f:
with open_compressed(path) as f:
tree = ET.parse(f)
for pkg in tree.getroot().findall(f"{{{OTHER_NS}}}package"):